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

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

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

一.話題引入

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

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

什么是JWT?

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

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

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

  • 引入JWT工具類,編寫生成令牌和解析令牌的方法。
  • 用戶登錄成功后生成令牌字符串返回給前端。
  • 前端每次請求時都在請求頭帶入令牌字符串。
  • 在通用模塊編寫攔截器,解析請求頭中的令牌字符串。
  • 在Api模塊配置攔截器,配置攔截器攔截哪些接口,即這些接口需要登錄才能訪問。

現(xiàn)在來編寫代碼實現(xiàn)

2.1 引入依賴

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

2.2 編寫JWT工具類

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過期時間,一天
    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ā)時間
                .withExpiresAt(new Date(new Date().getTime() + EXPIRE_DATE)) // 過期時間
                .withSubject(shoppingUser.getUsername()) // 保存用戶名
                .withClaim("userId",shoppingUser.getId()) // 保存用戶id
                .sign(Algorithm.HMAC256(SECRET)); // 秘鑰
        return token;
    }
    /**
     * 簽名解析
     * @param token 簽名字符串
     * @return 解析得出的用戶名
     */
    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);
        }
    }
    /**
     * 簽名解析,獲取用戶id
     * @param token 簽名字符串
     * @return 用戶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);
        }
    }
}

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

2.3 編寫登錄方法

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

在這里插入圖片描述

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

服務(wù)層

 @Override
    public String loginPassword(String username, String password) {
        // 1.驗證用戶名
        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.驗證密碼
        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;
    }

控制層

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

2.4 編寫JWT攔截器驗證令牌

這里驗證令牌的方式是攔截所有的請求,如果 JWTUtil.verify(token)不拋異常則通過這個請求。

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

2.5 編寫要配置攔截的接口

我們在用戶模塊配置該模塊要攔截的接口(如果是單體架構(gòu),攔截器和該部分可以寫在一起)。

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

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

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

至此,一個令牌認證就完成啦。

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

相關(guān)文章

  • Java面向?qū)ο笾畠?nèi)部類案例講解

    Java面向?qū)ο笾畠?nèi)部類案例講解

    這篇文章主要介紹了Java面向?qū)ο笾畠?nèi)部類案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 分析Java中ArrayList與LinkedList列表結(jié)構(gòu)的源碼

    分析Java中ArrayList與LinkedList列表結(jié)構(gòu)的源碼

    這篇文章主要介紹了Java中ArrayList與LinkedList列表結(jié)構(gòu)的源碼,文章最后對LinkedList和ArrayList以及Vector的特性有一個對比總結(jié),需要的朋友可以參考下
    2016-05-05
  • JAVA隨機打亂數(shù)組順序的方法

    JAVA隨機打亂數(shù)組順序的方法

    這篇文章主要介紹了JAVA隨機打亂數(shù)組順序的方法,包含了隨機數(shù)的應(yīng)用及數(shù)組的排序等操作,是Java操作數(shù)組的典型應(yīng)用,需要的朋友可以參考下
    2014-11-11
  • Java創(chuàng)建對象的四種方式詳解

    Java創(chuàng)建對象的四種方式詳解

    這篇文章主要介紹了Java創(chuàng)建對象的四種方式詳解,如果我們不想利用默認構(gòu)造器來創(chuàng)建java對象,而想利用指定的構(gòu)造器來創(chuàng)建java對象,則需要利用Construtor對象,每個Construtor對應(yīng)一個構(gòu)造器,需要的朋友可以參考下
    2023-11-11
  • Java利用正則表達式提取數(shù)據(jù)的方法

    Java利用正則表達式提取數(shù)據(jù)的方法

    最近由于項目需求需要提取txt里的數(shù)據(jù),之前用C#實現(xiàn)過,由于最近學習了java,所以嘗試用java實現(xiàn)下,這篇文章主要介紹了Java利用正則表達式提取數(shù)據(jù)的方法,需要的朋友可以參考下,下面來一起看看吧。
    2016-12-12
  • JVM內(nèi)存與CPU占用過高問題定位及解決

    JVM內(nèi)存與CPU占用過高問題定位及解決

    文章介紹了一種通過排查思路定位Java程序中CPU和內(nèi)存占用過高的問題的方法,通過運行一個模擬無限添加byte[]的代碼,使用top命令查看進程占用情況,然后通過查看線程列表和輸出堆棧信息,最終定位到具體的代碼方法
    2026-01-01
  • Spring Boot文件上傳簡單實例代碼

    Spring Boot文件上傳簡單實例代碼

    在本篇文章里小編給大家分享的是關(guān)于Spring Boot 文件上傳簡易教程以及相關(guān)知識點,需要的朋友們參考下。
    2019-08-08
  • java集合求和最大值最小值示例分享

    java集合求和最大值最小值示例分享

    這篇文章主要介紹了java集合求和最大值最小值示例
    2014-01-01
  • 使用spring連接及操作mongodb3.0實例

    使用spring連接及操作mongodb3.0實例

    這篇文章主要介紹了使用spring連接及操作mongodb3.0實例,詳細的介紹了使用spring的情況下,在java中簡單操作mongodb。有興趣的可以了解一下。
    2016-12-12
  • java查詢mongodb中的objectid示例

    java查詢mongodb中的objectid示例

    這篇文章主要介紹了java查詢mongodb中的objectid示例,需要的朋友可以參考下
    2014-04-04

最新評論

利川市| 南靖县| 长乐市| 保靖县| 贺兰县| 双辽市| 桂东县| 桂东县| 襄垣县| 承德县| 乌鲁木齐市| 丁青县| 太白县| 吴忠市| 安达市| 乐清市| 西乌珠穆沁旗| 民县| 信丰县| 虎林市| 吴忠市| 海兴县| 大安市| 大邑县| 孙吴县| 扶余县| 碌曲县| 林甸县| 张家港市| 桦甸市| 定结县| 虎林市| 绩溪县| 桐乡市| 剑川县| 齐齐哈尔市| 怀柔区| 五常市| 吉林省| 天长市| 祁阳县|