1. 程式人生 > 其它 >SpringBoot實現基於token的登入驗證

SpringBoot實現基於token的登入驗證

一.SpringBoot實現基於token的登入驗證

基於token的登入驗證實現原理:客戶端通過使用者名稱和密碼呼叫登入介面,當驗證資料庫中存在該使用者後,將使用者的資訊按照token的生成規則,生成一個字串token,返回給客戶端,客戶端在呼叫其他介面的時候,需要在請求頭上帶上token,來驗證登入資訊。

二.Demo實現程式碼如下:

(因為除登入介面外,其他介面每次都需要驗證token資訊,所以將驗證token資訊的部分放在了過濾器裡面)

1.匯入JWT(JSON WEB TOKEN)依賴

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
</dependency>

2.Jwt工具類,包括token的生成和驗證(加密祕鑰先自己隨便寫了一個)

@Component
public class JwtUitls {
    
    @Autowired
    private UserService userService;
    /**
     * 過期時間5分鐘
     */
     private static final long EXPIRE_TIME=5*60*1000;
    /**
     * 加密金鑰
     */
    private static final String KEY = "liuhongfei";

    /**
     * 生成token
     * 
@param id 使用者id * @param userName 使用者名稱 * @return */ public String createToken(String id,String userName){ Map<String,Object> header = new HashMap(); header.put("typ","JWT"); header.put("alg","HS256"); //setID:使用者ID //setExpiration:token過期時間 當前時間+有效時間
//setSubject:使用者名稱 //setIssuedAt:token建立時間 //signWith:加密方式 JwtBuilder builder = Jwts.builder().setHeader(header) .setId(id) .setExpiration(new Date(System.currentTimeMillis()+EXPIRE_TIME)) .setSubject(userName) .setIssuedAt(new Date()) .signWith(SignatureAlgorithm.HS256,KEY); return builder.compact(); } /** * 驗證token是否有效 * @param token 請求頭中攜帶的token * @return token驗證結果 2-token過期;1-token認證通過;0-token認證失敗 */ public int verify(String token){ Claims claims = null; try { //token過期後,會丟擲ExpiredJwtException 異常,通過這個來判定token過期, claims = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token).getBody(); }catch (ExpiredJwtException e){ return 2; } //從token中獲取使用者id,查詢該Id的使用者是否存在,存在則token驗證通過 String id = claims.getId(); User user = userService.selectUserById(id); if(user != null){ return 1; }else{ return 0; } } }

3.過濾器,實現filter介面

/**
* @description:
* @author: hwx
* @date: 2022/05/23
**/
@Order(1)
//如果我們有多個過濾器,那這個Order就可以指定優先順序
@Component
//這裡可以使用@Compent,也可以不加這個@Component,而是在@SpringBootApplication入口類上新增註解@ServletComponentScan。@Component也可以替換成@Configration
@WebFilter(urlPatterns = "/*",filterName = "myFilter")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("我是過濾器的初始化方法init");
}

@Override
public void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException {
System.out.println("我是過濾器的真正的執行方法doFilter,serverlet的請求,you are wanted one");
HttpServletResponse httpServletResponse=(HttpServletResponse)var2;
//允許的請求頭欄位
httpServletResponse.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
//是否允許後續請求攜帶認證資訊(cookies),該值只能是true,否則不返回
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
//指定允許其他域名訪問
httpServletResponse.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8070");
//引數 chain 為代表當前 Filter 鏈的物件。
var3.doFilter(var1,httpServletResponse);
System.out.println("我是過濾器的真正的執行方法doFilter,serverlet的請求,you are wanted two");
}

@Override
public void destroy() {
System.out.println("不行了,我要被銷燬了");
}
}

4.使用postman測試結果如下
(1)呼叫login介面,返回token

 (2)呼叫查詢使用者介面,在請求頭中加入token

 (3)不攜帶token,呼叫查詢介面

 (4)token過期後,呼叫查詢介面

 以上就是一個簡單的token登入機制
token登入機制的好處:不需要將登入資訊儲存在資料庫或session中
token中還可以攜帶更多的使用者資訊,包括許可權等