亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于JWT之token令牌認(rèn)證登錄

 更新時(shí)間:2023年05月22日 11:01:20   作者:獅子也瘋狂  
這篇文章主要介紹了關(guān)于JWT之token令牌認(rèn)證登錄,使用JWT能夠保證Token的安全性,且能夠進(jìn)行Token時(shí)效性的檢驗(yàn),使用JWT時(shí),登錄成功后將用戶(hù)信息生成一串令牌字符串,需要的朋友可以參考下

一.話(huà)題引入

在做項(xiàng)目過(guò)程中,我們一般都是最先編寫(xiě)登錄注冊(cè)功能,登錄功能最重要的是登錄成功后,系統(tǒng)還會(huì)保存該登錄用戶(hù)信息,這種保存用戶(hù)信息的邏輯可以有兩種:

  1. 最簡(jiǎn)單的一種就是使用Session來(lái)保存用戶(hù)信息,然后使用filter來(lái)驗(yàn)證用戶(hù)是否登錄,但是這種方法只能是單體架構(gòu)的項(xiàng)目適用,性能也不會(huì)很好。在分布式項(xiàng)目中,會(huì)有很多子模塊并且部署在不同的服務(wù)器中,這樣是無(wú)法使用session保存的,因?yàn)閟essio不能共享。
  2. 使用單點(diǎn)登錄技術(shù)就能很好地解決這個(gè)弊端。
    1. 單點(diǎn)登錄(Single Sign On)簡(jiǎn)稱(chēng)為 SSO。即在多個(gè)應(yīng)用系統(tǒng)中,用戶(hù)只需要登錄一次就可以訪(fǎng)問(wèn)所有相互信任的應(yīng)用系統(tǒng)。JWT是一種常用的單點(diǎn)登錄解決方案。

什么是JWT?

JWTJson Web Token的簡(jiǎn)稱(chēng),是一種令牌生成算法。使用JWT能夠保證Token的安全性,且能夠進(jìn)行Token時(shí)效性的檢驗(yàn)。使用JWT時(shí),登錄成功后將用戶(hù)信息生成一串令牌字符串。將該字符串返回給客戶(hù)端,客戶(hù)端每次請(qǐng)求時(shí)都在請(qǐng)求頭攜帶該令牌字符串。在其他模塊驗(yàn)證令牌,通過(guò)則證明用戶(hù)處于登錄狀態(tài),并拿到解析后的用戶(hù)信息,未通過(guò)證明用戶(hù)處于未登錄狀態(tài)。

二.技術(shù)體現(xiàn)

要實(shí)現(xiàn)JWT鑒權(quán),就得實(shí)現(xiàn)如下步驟:

  • 引入JWT工具類(lèi),編寫(xiě)生成令牌和解析令牌的方法。
  • 用戶(hù)登錄成功后生成令牌字符串返回給前端。
  • 前端每次請(qǐng)求時(shí)都在請(qǐng)求頭帶入令牌字符串。
  • 在通用模塊編寫(xiě)攔截器,解析請(qǐng)求頭中的令牌字符串。
  • 在A(yíng)pi模塊配置攔截器,配置攔截器攔截哪些接口,即這些接口需要登錄才能訪(fǎng)問(wèn)。

現(xiàn)在來(lái)編寫(xiě)代碼實(shí)現(xiàn)

2.1 引入依賴(lài)

<dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

2.2 編寫(xiě)JWT工具類(lèi)

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.itbaizhan.shopping_common.exception.BusException;
import com.itbaizhan.shopping_common.pojo.ShoppingUser;
import com.itbaizhan.shopping_common.result.CodeEnum;
import java.util.Date;
public class JWTUtil {
    //token過(guò)期時(shí)間,一天
    private static final Long EXPIRE_DATE = 1000*60*60*24L;
    // 秘鑰
    private static final String SECRET = "jackie";
    // 簽發(fā)者
    private static final String ISSUER = "JACKIE";
    /**
     * 簽名生成
     * @param shoppingUser
     * @return
     */
    public static String sign(ShoppingUser shoppingUser){
        String token = JWT.create()
                .withIssuer(ISSUER) // 簽發(fā)者
                .withIssuedAt(new Date()) // 簽發(fā)時(shí)間
                .withExpiresAt(new Date(new Date().getTime() + EXPIRE_DATE)) // 過(guò)期時(shí)間
                .withSubject(shoppingUser.getUsername()) // 保存用戶(hù)名
                .withClaim("userId",shoppingUser.getId()) // 保存用戶(hù)id
                .sign(Algorithm.HMAC256(SECRET)); // 秘鑰
        return token;
    }
    /**
     * 簽名解析
     * @param token 簽名字符串
     * @return 解析得出的用戶(hù)名
     */
    public static String verify(String token){
        try {
            String username = JWT
                    .require(Algorithm.HMAC256(SECRET))
                    .withIssuer(ISSUER)
                    .build()
                    .verify(token)
                    .getSubject();
            return username;
        } catch (Exception e){
            throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);
        }
    }
    /**
     * 簽名解析,獲取用戶(hù)id
     * @param token 簽名字符串
     * @return 用戶(hù)id
     */
    public static Long getId(String token){
        try {
            Long userId = JWT
                    .require(Algorithm.HMAC256(SECRET))
                    .withIssuer(ISSUER)
                    .build()
                    .verify(token)
                    .getClaim("userId")
                    .asLong();
            return userId;
        } catch (Exception e){
            throw new BusException(CodeEnum.VERIFY_TOKEN_ERROR);
        }
    }
}

這個(gè)utils有三個(gè)方法,一個(gè)是生成token字符串,一個(gè)是解析該字符串獲取登錄的用戶(hù)名,還要就是獲取登錄用戶(hù)的id。

2.3 編寫(xiě)登錄方法

如果使用Session存儲(chǔ)用戶(hù)信息,在驗(yàn)證完名字和密碼后,直接將該登錄對(duì)象setAttribute(“users”,users)里面。

在這里插入圖片描述

而使用單點(diǎn)登錄,則是直接調(diào)用JWTUtil.sign(user),生成JWT令牌,返回該令牌給前端用戶(hù)。 標(biāo)準(zhǔn)代碼:

服務(wù)層

 @Override
    public String loginPassword(String username, String password) {
        // 1.驗(yàn)證用戶(hù)名
        QueryWrapper<ShoppingUser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("username",username);
        ShoppingUser shoppingUser = shoppingUserMapper.selectOne(queryWrapper);
        if (shoppingUser == null){
            throw new BusException(CodeEnum.LOGIN_NAME_PASSWORD_ERROR);
        }
        // 2.驗(yàn)證密碼
        boolean verify = Md5Util.verify(password, shoppingUser.getPassword());
        if (!verify){
            throw new BusException(CodeEnum.LOGIN_NAME_PASSWORD_ERROR);
        }
        // 3.生成JWT令牌,返回令牌
        String sign = JWTUtil.sign(shoppingUser);
        return sign;
    }

控制層

 /**
     * 用戶(hù)名密碼登錄
     * @param shoppingUser 用戶(hù)對(duì)象
     * @return 登錄結(jié)果
     */
    @PostMapping("/loginPassword")
    public BaseResult loginPassword(@RequestBody ShoppingUser shoppingUser){
        String sign = shoppingUserService.loginPassword(shoppingUser.getUsername(), shoppingUser.getPassword());
        return BaseResult.ok(sign);
    }

2.4 編寫(xiě)JWT攔截器驗(yàn)證令牌

這里驗(yàn)證令牌的方式是攔截所有的請(qǐng)求,如果 JWTUtil.verify(token)不拋異常則通過(guò)這個(gè)請(qǐng)求。

// 攔截器,驗(yàn)證令牌
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 獲取請(qǐng)求頭中的token
        String token = request.getHeader("token");
        // 驗(yàn)證令牌
        JWTUtil.verify(token);
        return true;
    }
}

2.5 編寫(xiě)要配置攔截的接口

我們?cè)谟脩?hù)模塊配置該模塊要攔截的接口(如果是單體架構(gòu),攔截器和該部分可以寫(xiě)在一起)。

除了這種方式,還有一種編寫(xiě)方式,你想知道嗎?

在User模塊先實(shí)例化一個(gè)InterceptorConfig配置類(lèi),實(shí)現(xiàn)WebMvcConfigurer接口,將上面寫(xiě)的攔截器在addInterceptor(new JWTInterceptor())方法里面實(shí)例化,然后攔截所有的接口( .addPathPatterns(“/**”)),再放行不需要認(rèn)證的接口。

// 攔截器配置
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/**") // 攔截的接口
                .excludePathPatterns(
                       "填寫(xiě)需要放行的接口url"
                ); //放行的接口
    }
}

至此,一個(gè)令牌認(rèn)證就完成啦。

到此這篇關(guān)于關(guān)于JWT之token令牌認(rèn)證登錄的文章就介紹到這了,更多相關(guān)token令牌認(rèn)證登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java自定義封裝StringUtils常用工具類(lèi)

    java自定義封裝StringUtils常用工具類(lèi)

    這篇文章主要為大家詳細(xì)介紹了java自定義封裝StringUtils常用工具類(lèi),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 解決Springboot不能自動(dòng)提交數(shù)據(jù)庫(kù)連接問(wèn)題

    解決Springboot不能自動(dòng)提交數(shù)據(jù)庫(kù)連接問(wèn)題

    在使用SSM框架開(kāi)發(fā)時(shí),若在同一Service內(nèi)部方法間互相調(diào)用,直接使用this關(guān)鍵字會(huì)導(dǎo)致事務(wù)管理失效,從而引發(fā)如數(shù)據(jù)庫(kù)連接不足等問(wèn)題,原因是通過(guò)this調(diào)用不會(huì)經(jīng)過(guò)Spring的代理,因此不會(huì)自動(dòng)進(jìn)行事務(wù)處理
    2024-09-09
  • 什么是Java多線(xiàn)程,如何實(shí)現(xiàn)

    什么是Java多線(xiàn)程,如何實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于實(shí)現(xiàn)Java多線(xiàn)程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧吧
    2021-11-11
  • Java通過(guò)python命令執(zhí)行DataX任務(wù)的實(shí)例

    Java通過(guò)python命令執(zhí)行DataX任務(wù)的實(shí)例

    今天小編就為大家分享一篇Java通過(guò)python命令執(zhí)行DataX任務(wù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • 淺談Spring5 響應(yīng)式編程

    淺談Spring5 響應(yīng)式編程

    本篇文章主要介紹了淺談Spring5 響應(yīng)式編程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • JAVA多線(xiàn)程知識(shí)匯總

    JAVA多線(xiàn)程知識(shí)匯總

    這篇文章主要介紹了JAVA多線(xiàn)程的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • 一文讀懂Spring Bean的生命周期

    一文讀懂Spring Bean的生命周期

    今天我們來(lái)說(shuō)一說(shuō) Spring Bean 的生命周期,小伙伴們應(yīng)該在面試中經(jīng)常遇到,這是正?,F(xiàn)象,本文讓更多的小伙伴們可以輕松的讀懂 Spring Bean 的生命周期
    2023-03-03
  • 簡(jiǎn)單談?wù)凧ava中的棧和堆

    簡(jiǎn)單談?wù)凧ava中的棧和堆

    堆和棧都是Java用來(lái)在RAM中存放數(shù)據(jù)的地方,下面這篇文章主要給大家介紹了關(guān)于Java中棧和堆的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • 分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證

    分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證

    這篇文章主要為大家介紹分析xxljob登入功能集成OIDC的統(tǒng)一認(rèn)證的詳解說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • Java使用RedisTemplate模糊刪除key操作

    Java使用RedisTemplate模糊刪除key操作

    這篇文章主要介紹了Java使用RedisTemplate模糊刪除key操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11

最新評(píng)論