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

SpringBoot實現(xiàn)JWT認證的完整方案

 更新時間:2025年10月23日 08:22:58   作者:匆匆忙忙游刃有余  
JWT(JSON?Web?Token)是一種用于在網(wǎng)絡(luò)應(yīng)用間安全傳遞信息的開放標準,特別適合分布式系統(tǒng)的身份驗證,下面我將詳細介紹如何在SpringBoot項目中實現(xiàn)JWT認證的完整方案,需要的朋友可以參考下

引言

JWT(JSON Web Token)是一種用于在網(wǎng)絡(luò)應(yīng)用間安全傳遞信息的開放標準,特別適合分布式系統(tǒng)的身份驗證。下面我將詳細介紹如何在SpringBoot項目中實現(xiàn)JWT認證。

一、JWT 基礎(chǔ)概念

JWT由三部分組成,用.連接:

  1. Header(頭部):包含令牌類型和使用的加密算法
  2. Payload(載荷):包含用戶信息和聲明
  3. Signature(簽名):使用密鑰對前兩部分進行簽名,確保信息不被篡改

二、項目準備

1. 添加依賴

pom.xml中添加JWT相關(guān)依賴:

<!-- JWT依賴 -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.2</version>
</dependency>
<!-- Spring Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok(可選,用于簡化代碼) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2. 配置文件

application.yml中添加JWT相關(guān)配置:

spring:
  application:
    name: springboot-jwt-demo

jwt:
  # 密鑰
  secret: your-secret-key-change-in-production
  # 過期時間(毫秒)
  expire-time: 86400000
  # 請求頭中Token的名稱
  header: Authorization
  # Token前綴
  token-prefix: Bearer

三、核心代碼實現(xiàn)

1. JWT工具類

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Map;

@Component
public class JWTUtil {
    
    @Value("${jwt.secret}")
    private String secret;
    
    @Value("${jwt.expire-time}")
    private long expireTime;
    
    /**
     * 生成Token
     * @param claims 要存儲在Token中的信息
     * @return 生成的Token字符串
     */
    public String generateToken(Map<String, String> claims) {
        // 設(shè)置過期時間
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MILLISECOND, (int) expireTime);
        
        // 創(chuàng)建JWT Builder
        JWTCreator.Builder builder = JWT.create();
        
        // 添加載荷
        claims.forEach(builder::withClaim);
        
        // 設(shè)置簽名和過期時間,生成Token
        return builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(secret));
    }
    
    /**
     * 驗證Token
     * @param token 要驗證的Token
     * @return 驗證后的DecodedJWT對象
     * @throws JWTVerificationException 驗證失敗時拋出異常
     */
    public DecodedJWT verifyToken(String token) {
        return JWT.require(Algorithm.HMAC256(secret))
                .build()
                .verify(token);
    }
    
    /**
     * 解析Token
     * @param token 要解析的Token
     * @return 解析后的DecodedJWT對象
     */
    public DecodedJWT parseToken(String token) {
        return JWT.decode(token);
    }
    
    /**
     * 從Token中獲取指定的Claim
     * @param token Token字符串
     * @param claimName Claim名稱
     * @return Claim值
     */
    public String getClaim(String token, String claimName) {
        DecodedJWT decodedJWT = parseToken(token);
        return decodedJWT.getClaim(claimName).asString();
    }
}

2. JWT攔截器

import com.auth0.jwt.exceptions.JWTVerificationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Component
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {
    
    @Autowired
    private JWTUtil jwtUtil;
    
    @Value("${jwt.header}")
    private String jwtHeader;
    
    @Value("${jwt.token-prefix}")
    private String tokenPrefix;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader(jwtHeader);
        
        // 檢查請求頭中是否包含Token
        if (token == null || "".equals(token.trim())) {
            response401(response, "Token不存在");
            return false;
        }
        
        // 移除Token前綴
        if (token.startsWith(tokenPrefix)) {
            token = token.replace(tokenPrefix, "").trim();
        } else {
            response401(response, "Token格式錯誤");
            return false;
        }
        
        try {
            // 驗證Token
            jwtUtil.verifyToken(token);
            log.info("Token驗證成功");
            return true;
        } catch (JWTVerificationException e) {
            log.error("Token驗證失敗: {}", e.getMessage());
            response401(response, "Token無效或已過期");
            return false;
        }
    }
    
    /**
     * 返回401錯誤響應(yīng)
     */
    private void response401(HttpServletResponse response, String message) {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        
        try (PrintWriter out = response.getWriter()) {
            out.append("{\"code\": 401, \"message\": \"").append(message).append("\"}");
        } catch (Exception e) {
            log.error("響應(yīng)錯誤: {}", e.getMessage());
        }
    }
}

3. 攔截器配置

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 InterceptorConfig implements WebMvcConfigurer {
    
    @Autowired
    private JWTInterceptor jwtInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加攔截器,攔截需要認證的路徑
        registry.addInterceptor(jwtInterceptor)
                // 需要攔截的路徑
                .addPathPatterns("/api/**")
                // 排除不需要攔截的路徑
                .excludePathPatterns("/api/login", "/api/register", "/error");
    }
}

4. 實體類

import lombok.Data;

@Data
public class LoginRequest {
    private String username;
    private String password;
}

@Data
public class LoginResponse {
    private String token;
    private String username;
    private String message;
}

5. 用戶服務(wù)接口

public interface UserService {
    boolean login(String username, String password);
    boolean register(String username, String password);
}

6. 用戶服務(wù)實現(xiàn)

import org.springframework.stereotype.Service;

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

@Service
public class UserServiceImpl implements UserService {
    
    // 模擬數(shù)據(jù)庫,實際項目中應(yīng)使用數(shù)據(jù)庫存儲
    private final Map<String, String> userMap = new HashMap<>();
    
    public UserServiceImpl() {
        // 初始化測試用戶
        userMap.put("admin", "123456");
    }
    
    @Override
    public boolean login(String username, String password) {
        return userMap.containsKey(username) && userMap.get(username).equals(password);
    }
    
    @Override
    public boolean register(String username, String password) {
        if (userMap.containsKey(username)) {
            return false; // 用戶名已存在
        }
        userMap.put(username, password);
        return true;
    }
}

7. 登錄控制器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/api")
public class AuthController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private JWTUtil jwtUtil;
    
    @Value("${jwt.token-prefix}")
    private String tokenPrefix;
    
    /**
     * 用戶登錄
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        if (userService.login(request.getUsername(), request.getPassword())) {
            // 構(gòu)建Token中的載荷信息
            Map<String, String> claims = new HashMap<>();
            claims.put("username", request.getUsername());
            
            // 生成Token
            String token = jwtUtil.generateToken(claims);
            
            // 構(gòu)建響應(yīng)
            LoginResponse response = new LoginResponse();
            response.setToken(tokenPrefix + " " + token);
            response.setUsername(request.getUsername());
            response.setMessage("登錄成功");
            
            return ResponseEntity.ok(response);
        }
        return ResponseEntity.badRequest().body("用戶名或密碼錯誤");
    }
    
    /**
     * 用戶注冊
     */
    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody LoginRequest request) {
        if (userService.register(request.getUsername(), request.getPassword())) {
            return ResponseEntity.ok("注冊成功");
        }
        return ResponseEntity.badRequest().body("用戶名已存在");
    }
    
    /**
     * 測試接口,需要驗證Token
     */
    @GetMapping("/test")
    public ResponseEntity<?> test() {
        return ResponseEntity.ok("訪問成功,Token有效");
    }
}

四、安全性考慮

  1. 密鑰安全:密鑰必須保密,生產(chǎn)環(huán)境應(yīng)使用強密鑰
  2. Token過期時間:設(shè)置合理的過期時間,避免永久有效
  3. HTTPS傳輸:在生產(chǎn)環(huán)境中使用HTTPS傳輸Token
  4. 防XSS攻擊:Token存儲在localStorage時可能被XSS攻擊竊取
  5. Token刷新機制:實現(xiàn)Token刷新機制,避免頻繁登錄
  6. 黑名單機制:對于已注銷的Token,添加到黑名單中

五、優(yōu)化建議

  1. 使用Redis存儲Token:可以更靈活地管理Token生命周期
  2. 實現(xiàn)Refresh Token:提供長期的Refresh Token用于獲取新的Access Token
  3. 增加角色權(quán)限:在Token中添加用戶角色信息,實現(xiàn)更細粒度的權(quán)限控制
  4. 使用非對稱加密:生產(chǎn)環(huán)境可考慮使用RSA等非對稱加密算法
  5. 添加IP綁定:在Token中綁定用戶IP,增加安全性
  6. 添加日志記錄:記錄Token的生成、驗證和使用情況

六、測試方法

  1. 啟動SpringBoot應(yīng)用
  2. 使用Postman或其他工具測試登錄接口:POST http://localhost:8080/api/login
  3. 在請求體中添加用戶名和密碼
  4. 成功后將返回的Token添加到請求頭
  5. 訪問需要認證的接口:GET http://localhost:8080/api/test

這個實現(xiàn)提供了SpringBoot中JWT認證的完整流程,包括Token生成、驗證和攔截器實現(xiàn)。您可以根據(jù)實際需求進行調(diào)整和擴展。

以上就是SpringBoot實現(xiàn)JWT認證的完整方案的詳細內(nèi)容,更多關(guān)于SpringBoot JWT認證的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java調(diào)用接口返回亂碼問題及解決

    java調(diào)用接口返回亂碼問題及解決

    這篇文章主要介紹了java調(diào)用接口返回亂碼問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • springboot 打包 failed with MalformedInputException: Input length=1

    springboot 打包 failed with MalformedInput

    本文主要介紹了SpringBoot項目在打包時常見的錯誤,通常是由于資源文件的編碼問題導(dǎo)致的,下面就一起來介紹一下該問題的詳細步驟,感興趣的可以了解一下
    2025-07-07
  • Springboot如何通過自定義工具類獲取bean

    Springboot如何通過自定義工具類獲取bean

    這篇文章主要介紹了Springboot通過自定義工具類獲取bean方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 詳解Spring框架之基于Restful風(fēng)格實現(xiàn)的SpringMVC

    詳解Spring框架之基于Restful風(fēng)格實現(xiàn)的SpringMVC

    這篇文章主要介紹了詳解Spring框架之基于Restful風(fēng)格實現(xiàn)的SpringMVC,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Spring與Spring boot的區(qū)別介紹

    Spring與Spring boot的區(qū)別介紹

    Spring Boot框架的核心就是自動配置,只要存在相應(yīng)的jar包,Spring就幫我們自動配置。接下來通過本文給大家介紹Spring與Spring boot的區(qū)別介紹,非常不錯,需要的朋友參考下吧
    2017-04-04
  • Java中的這些騷操作你不能不知道!!!

    Java中的這些騷操作你不能不知道!!!

    今天在看python相關(guān)的東西,看到各種騷操作,回頭想了下Java有沒有什么騷操作,整理下面幾種,一起看一下吧,希望能給你帶來幫助
    2021-07-07
  • Java中File類方法詳解以及實踐

    Java中File類方法詳解以及實踐

    Java File類的功能非常強大,利用java基本上可以對文件進行所有操作,下面這篇文章主要給大家介紹了關(guān)于Java中File類方法以及實踐的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • Java線程間共享實現(xiàn)方法詳解

    Java線程間共享實現(xiàn)方法詳解

    這篇文章主要介紹了Java線程間共享實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • maven搭建java ee項目圖文教程

    maven搭建java ee項目圖文教程

    這篇文章主要為大家詳細介紹了maven搭建java ee項目圖文教程,感興趣的小伙伴們可以參考一下
    2016-04-04
  • 如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)詳解

    如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)詳解

    工作中經(jīng)常會有定時任務(wù)的需求,常見的做法可以使用Timer、Quartz、Hangfire等組件,這次想嘗試下新的思路,使用RabbitMQ死信隊列的機制來實現(xiàn)定時任務(wù),下面這篇文章主要給大家介紹了關(guān)于如何通過RabbitMq實現(xiàn)動態(tài)定時任務(wù)的相關(guān)資料,需要的朋友可以參考下
    2022-01-01

最新評論

亳州市| 沐川县| 应用必备| 吉安县| 汉川市| 阳原县| 衡阳市| 达孜县| 济源市| 海原县| 清河县| 漯河市| 陆川县| 承德市| 茌平县| 湘潭市| 湛江市| 武宣县| 宣威市| 酒泉市| 长治市| 门头沟区| 淮安市| 乐安县| 武平县| 镇江市| 仪征市| 清徐县| 城市| 巴马| 会理县| 兴业县| 潍坊市| 临漳县| 马关县| 铜川市| 日土县| 安陆市| 迁安市| 兴义市| 华安县|