欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一次學(xué)會JWT之Java登錄、驗證與權(quán)限控制完整流程

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

1. JWT 基礎(chǔ)概念

1.1 什么是 JWT?

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

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

1.2 為什么要用 JWT?

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

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

  • 多臺服務(wù)器要共享 Session,需要引入 Redis

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

JWT(JSON Web Token)

  • 無需服務(wù)端保存狀態(tài),無狀態(tài)認(rèn)證

  • Token 自包含用戶信息

  • 輕量、安全、跨平臺

1.3 JWT 的結(jié)構(gòu)

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用戶唯一標(biāo)識(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. 用戶登錄 → 服務(wù)器驗證身份

  2. 服務(wù)器生成 JWT 并返回給客戶端

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

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

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

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

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

3.6 編寫受保護(hù)接口

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 "當(dāng)前用戶:" + username + ",角色:" + role;
    }
}

3.7 項目結(jié)構(gòu)圖

jwt
│── pom.xml                # Maven 依賴
│── src
│   ├── main
│   │   ├── java
│   │   │   └── com.yq.jwt
│   │   │       ├── config
│   │   │       │    └── WebConfig.java          # 配置攔截器
│   │   │       ├── controller
│   │   │       │    ├── AuthController.java     # 登錄接口
│   │   │       │    └── UserController.java     # 受保護(hù)接口
│   │   │       ├── 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 訪問受保護(hù)接口

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

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

5. 總結(jié)

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

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

相關(guān)文章

  • 一篇文章讓你弄懂Java運算符

    一篇文章讓你弄懂Java運算符

    java中位運算符主要有按位與&、按位或|、按位非~、按位異或^, 在使用時需要將運算數(shù)都轉(zhuǎn)換為二進(jìn)制再進(jìn)行運算,若為負(fù)數(shù)則使用補碼表示,這篇文章主要給大家介紹了關(guān)于Java運算符的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • 解讀List?list=new?ArrayList()是怎么回事

    解讀List?list=new?ArrayList()是怎么回事

    這篇文章主要介紹了解讀List?list=new?ArrayList()是怎么回事,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 關(guān)于@ComponentScan注解的用法及作用說明

    關(guān)于@ComponentScan注解的用法及作用說明

    這篇文章主要介紹了關(guān)于@ComponentScan注解的用法及作用說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 深入探討Java 中的 Object 類詳解(一切類的根基)

    深入探討Java 中的 Object 類詳解(一切類的根基)

    本文詳細(xì)介紹了Java中的Object類,作為所有類的根類,其重要性不言而喻,文章涵蓋了Object類的主要方法,如toString()、equals()、hashCode()等,本文深入探討 Object 類的作用、常用方法以及如何在實際開發(fā)中利用這些方法,感興趣的朋友一起看看吧
    2025-01-01
  • 匯總Java中List 去重的 6 種方法

    匯總Java中List 去重的 6 種方法

    這篇文章主要介紹了匯總Java中List 去重的 6 種方法,文章圍繞主題展開List去重的方法,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • 簡單了解java獲取類的3種方式

    簡單了解java獲取類的3種方式

    這篇文章主要介紹了java獲取類的3種方式詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • SpringLDAP目錄服務(wù)之LdapTemplate與LDAP操作方式

    SpringLDAP目錄服務(wù)之LdapTemplate與LDAP操作方式

    本文將深入探討Spring LDAP的核心概念、LdapTemplate的使用方法以及如何執(zhí)行常見的LDAP操作,幫助開發(fā)者有效地將LDAP集成到Spring應(yīng)用中,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • JSON字符串轉(zhuǎn)成java的Map對象詳細(xì)步驟

    JSON字符串轉(zhuǎn)成java的Map對象詳細(xì)步驟

    這篇文章主要介紹了如何將JSON字符串轉(zhuǎn)換為Java對象的步驟,包括定義Element類、使用Jackson庫解析JSON和添加依賴,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • Spring 開發(fā)過程中Value 注解的使用場景

    Spring 開發(fā)過程中Value 注解的使用場景

    這篇文章主要介紹了Spring 開發(fā)過程中Value 注解的使用場景,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下
    2020-11-11
  • IDEA+Maven創(chuàng)建Spring項目的實現(xiàn)步驟

    IDEA+Maven創(chuàng)建Spring項目的實現(xiàn)步驟

    這篇文章主要介紹了IDEA+Maven創(chuàng)建Spring項目的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論