最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一次學會JWT之Java登錄、驗證與權限控制完整流程

 更新時間:2025年09月22日 10:15:35   作者:YangQ27  
JWT(JSON Web Token)是一種開放標準(RFC 7519),用于在網(wǎng)絡應用環(huán)境間以緊湊的方式安全地傳遞信息,這篇文章主要介紹了JWT Java登錄、驗證與權限控制的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

1. JWT 基礎概念

1.1 什么是 JWT?

JWT(JSON Web Token)是一種基于 JSON 的輕量級認證方式,用于在各方之間安全地傳遞信息。它常用于 前后端分離項目的登錄認證,替代傳統(tǒng)的 Session 機制。

特點:數(shù)據(jù)量小,傳輸快(輕量)、本身攜帶用戶信息,不依賴服務端存儲(自包含)、簽名保證數(shù)據(jù)完整性與可信度(簽名防篡改)。

1.2 為什么要用 JWT?

傳統(tǒng)的登錄認證方式使用 Session 保存用戶信息,但在 前后端分離 項目中:

  • Session 需要服務端存儲,會增加服務器壓力

  • 多臺服務器要共享 Session,需要引入 Redis

  • 移動端、小程序調(diào)用不方便

JWT(JSON Web Token)

  • 無需服務端保存狀態(tài),無狀態(tài)認證

  • Token 自包含用戶信息

  • 輕量、安全、跨平臺

1.3 JWT 的結(jié)構

JWT 一般由三部分組成,用 . 分隔:

Header.Payload.Signature

Header(頭部)

聲明簽名算法和類型,例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

alg: 使用的簽名算法,如 HS256(HMAC SHA-256)、RS256(RSA SHA-256)等。

typ: 類型,固定為 JWT。

Payload(載荷)

存放實際信息(Claims),分為:

  • Registered claims(注冊字段):如 iss(簽發(fā)者)、exp(過期時間)等

  • Public claims(公共字段):自定義但公開的字段

  • Private claims(私有字段):自定義且內(nèi)部使用

常用的字段(大家約定俗稱的字段,表示一些通用的信息)

字段含義示例
sub用戶唯一標識(Subject)"sub": "user_10086"
exp過期時間(Expiration)"exp": 1723545600(時間戳)
iat簽發(fā)時間(Issued At)"iat": 1723459200
iss簽發(fā)者(Issuer)"iss": "myapp.com"

? 提醒:exp 最常用,用來控制 token 的有效期。

{
  "sub": "user123",
  "exp": 1723545600,
  "iss": "Yq",
  "iat": 1723459200,
}

自定義信息(這部分是你自己決定要告訴別人的信息)

{
  "name": "Yang",
  "role": "管理員",
  "email": "YangQ@example.com"
}

?? 注意:Payload 是 Base64 編碼的,不是加密的! 所以不要在其中存放敏感信息(如密碼)。

Signature(簽名)

用密鑰和前兩部分生成的簽名,防止數(shù)據(jù)被篡改。如(使用HMAC SHA256):

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

2. JWT 的工作流程

  1. 用戶登錄 → 服務器驗證身份

  2. 服務器生成 JWT 并返回給客戶端

  3. 客戶端每次請求都帶上 JWT(通常放在 HTTP Header 中 Authorization: Bearer <token>

  4. 服務器驗證 JWT 的合法性 → 允許訪問資源

優(yōu)點:無狀態(tài)、輕量、跨域支持

缺點:無法輕易撤銷(需維護黑名單)

3. Java中操作JWT

Java 生態(tài)中最流行的 JWT 庫是 jjwt,由 Apache 提供,簡單易用。

3.1 我們先創(chuàng)建 Spring Boot 項目并引入依賴

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- JWT -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-api</artifactId>
        <version>0.11.5</version>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-impl</artifactId>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt-jackson</artifactId>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

3.2 再封裝一個JwtUtil工具類,用于生成和驗證 Token。

package com.yg.jwt.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;

public class JwtUtil {
    // 建議從配置文件讀取
    private static final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    private static final long EXPIRATION = 60 * 1000; // 1分鐘

    // 生成 Token
    public static String generateToken(String username, String role) {
        return Jwts.builder()
                .setSubject(username)
                .claim("role", role)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .signWith(key)
                .compact();
    }

    // 解析 Token
    public static Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
}

3.3 實現(xiàn)登錄接口

package com.yg.jwt.controller;

import org.springframework.web.bind.annotation.*;
import com.yg.jwt.util.JwtUtil;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public Map<String, Object> login(@RequestParam String username, @RequestParam String password) {
        Map<String, Object> result = new HashMap<>();

        // 模擬賬號密碼驗證
        if ("admin".equals(username) && "123456".equals(password)) {
            String token = JwtUtil.generateToken(username, "admin");
            result.put("code", 200);
            result.put("message", "登錄成功");
            result.put("token", token);
        } else {
            result.put("code", 401);
            result.put("message", "用戶名或密碼錯誤");
        }
        return result;
    }
}

3.4 創(chuàng)建一個攔截器(JwtInterceptor.java)

攔截請求,用來驗證 Token 是否有效。

package com.yg.jwt.interceptor;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import com.yg.jwt.util.JwtUtil;


@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authHeader = request.getHeader("Authorization");

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);

            try {
                Claims claims = JwtUtil.parseToken(token);
                request.setAttribute("username", claims.getSubject());
                request.setAttribute("role", claims.get("role"));
                return true;
            } catch (ExpiredJwtException e) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("Token 已過期");
                return false;
            } catch (Exception e) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("無效 Token");
                return false;
            }
        }
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().write("缺少 Token");
        return false;
    }
}

3.5 配置攔截器

package com.yg.jwt.config;

import com.yg.jwt.interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private JwtInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/auth/login"); // 登錄接口放行
    }
}

?? 小插曲:為什么要配置攔截器?

因為MVC 框架需要知道“有哪些攔截器要工作”(注冊機制)、統(tǒng)一處理(避免在每個 Controller 里重復寫驗證邏輯)、全局控制(可以精確控制攔截哪些路徑、放行哪些路徑)、流程集成(攔截器是 MVC 生命周期的一部分,必須接入流程)

3.6 編寫受保護接口

package com.yg.jwt.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/info")
    public String getUserInfo(@RequestAttribute("username") String username,
                              @RequestAttribute("role") String role) {
        return "當前用戶:" + username + ",角色:" + role;
    }
}

3.7 項目結(jié)構圖

jwt
│── pom.xml                # Maven 依賴
│── src
│   ├── main
│   │   ├── java
│   │   │   └── com.yq.jwt
│   │   │       ├── config
│   │   │       │    └── WebConfig.java          # 配置攔截器
│   │   │       ├── controller
│   │   │       │    ├── AuthController.java     # 登錄接口
│   │   │       │    └── UserController.java     # 受保護接口
│   │   │       ├── interceptor
│   │   │       │    └── JwtInterceptor.java     # JWT 攔截器
│   │   │       └── util
│   │   │            └── JwtUtil.java            # JWT 工具類
│   │   └── resources
│   │        └── application.yml                 # 配置文件
│   └── test                                     
│        └── java                                 # 測試代碼

4. 測試流程

本篇章用的測試工具為Apifox,使用其他測試工具也是可以的(如:Postman)。

4.1 登錄獲取 Token

POST http://localhost:8080/auth/login
參數(shù):
username=admin
password=123456

返回:

4.2 訪問受保護接口

GET http://localhost:8080/user/info
Header:
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

把剛剛從后端返回回來的token放到Headers里面,接著訪問后端請求數(shù)據(jù)

5. 總結(jié)

JWT 是一種輕量、跨域、無狀態(tài)的認證方式,非常適合現(xiàn)代 Web 和微服務架構。通過 Java 的 jjwt 庫,我們可以快速生成、解析和驗證 JWT,實現(xiàn)安全的身份驗證機制。

到此這篇關于一次學會JWT之Java登錄、驗證與權限控制完整流程的文章就介紹到這了,更多相關Java登錄、驗證與權限控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis自定義typeHandle過程解析

    Mybatis自定義typeHandle過程解析

    這篇文章主要介紹了Mybatis自定義typeHandle過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java截取網(wǎng)頁圖片的方法

    java截取網(wǎng)頁圖片的方法

    這篇文章主要介紹了java截取網(wǎng)頁圖片的方法,涉及java調(diào)用第三方控件實現(xiàn)截圖的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • MyEclipse如何將項目的開發(fā)環(huán)境與服務器的JDK 版本保持一致

    MyEclipse如何將項目的開發(fā)環(huán)境與服務器的JDK 版本保持一致

    我們使用MyEclipse開發(fā)Java項目開發(fā)中,偶爾會遇到因項目開發(fā)環(huán)境不協(xié)調(diào),導致這樣那樣的問題,在這里以把所有環(huán)境調(diào)整為JDK1.6 為例,給大家詳細介紹MyEclipse如何將項目的開發(fā)環(huán)境與服務器的JDK 版本保持一致,需要的朋友參考下吧
    2024-04-04
  • java中l(wèi)ong(Long)與int(Integer)之間的轉(zhuǎn)換方式

    java中l(wèi)ong(Long)與int(Integer)之間的轉(zhuǎn)換方式

    這篇文章主要介紹了java中l(wèi)ong(Long)與int(Integer)之間的轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Mybatis-Plus樂觀鎖配置流程

    Mybatis-Plus樂觀鎖配置流程

    這篇文章主要介紹了Mybatis-Plus樂觀鎖配置使用流程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作有一定的參考學習價值,感興趣的朋友們下面隨著小編來一起學習吧
    2024-01-01
  • spring security自定義登錄頁面

    spring security自定義登錄頁面

    在項目中我們肯定不能使用Spring自己生成的登錄頁面,而要用我們自己的登錄頁面,下面通過本文給大家分享spring security自定義登錄頁面的實現(xiàn)方法,一起看看吧
    2017-09-09
  • SpringBoot配置Profile實現(xiàn)多環(huán)境支持

    SpringBoot配置Profile實現(xiàn)多環(huán)境支持

    這篇文章主要介紹了SpringBoot配置Profile實現(xiàn)多環(huán)境支持操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring AI框架結(jié)合Sentinel實現(xiàn)限流功能

    Spring AI框架結(jié)合Sentinel實現(xiàn)限流功能

    這篇文章主要為大家詳細介紹了如何實現(xiàn)一個簡單的使用Spring AI框架結(jié)合Sentinel限流的功能,場景是一個智能客服系統(tǒng),感興趣的小伙伴可以了解下
    2025-06-06
  • java8 集合求差集、并集、交集的實例

    java8 集合求差集、并集、交集的實例

    下面小編就為大家分享一篇java8 集合求差集、并集、交集的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Java線程之線程同步synchronized和volatile詳解

    Java線程之線程同步synchronized和volatile詳解

    這篇文章主要介紹了Java線程之線程同步synchronized和volatile詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11

最新評論

雅安市| 沁源县| 措勤县| 通州区| 新巴尔虎左旗| 洛宁县| 开阳县| 涟源市| 寿光市| 浠水县| 辽中县| 曲麻莱县| 麦盖提县| 佛坪县| 山东省| 德安县| 清水河县| 泗阳县| 本溪市| 彭山县| 瑞安市| 清水县| 莒南县| 隆化县| 常德市| 唐山市| 嘉鱼县| 林芝县| 开原市| 宜章县| 巍山| 化州市| 观塘区| 颍上县| 罗江县| 安国市| 聊城市| 临洮县| 鄂伦春自治旗| 陵川县| 宣城市|