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

關(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í),登錄成功后將用戶信息生成一串令牌字符串,需要的朋友可以參考下

一.話題引入

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

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

什么是JWT?

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

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

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

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

現(xiàn)在來編寫代碼實(shí)現(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過期時(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)) // 過期時(shí)間
                .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);
        }
    }
}

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

2.3 編寫登錄方法

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

在這里插入圖片描述

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

服務(wù)層

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

控制層

 /**
     * 用戶名密碼登錄
     * @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攔截器驗(yàn)證令牌

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

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

2.5 編寫要配置攔截的接口

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

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

在User模塊先實(shí)例化一個(gè)InterceptorConfig配置類,實(shí)現(xiàn)WebMvcConfigurer接口,將上面寫的攔截器在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(
                       "填寫需要放行的接口url"
                ); //放行的接口
    }
}

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

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

相關(guān)文章

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

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

    這篇文章主要介紹了Java面向?qū)ο笾畠?nèi)部類案例講解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(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的特性有一個(gè)對比總結(jié),需要的朋友可以參考下
    2016-05-05
  • JAVA隨機(jī)打亂數(shù)組順序的方法

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

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

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

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

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

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

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

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

    Spring Boot文件上傳簡單實(shí)例代碼

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

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

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

    使用spring連接及操作mongodb3.0實(shí)例

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

    java查詢mongodb中的objectid示例

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

最新評論

绥芬河市| 封丘县| 磐石市| 英超| 广水市| 东乡县| 赫章县| 巧家县| 鲁山县| 蕉岭县| 沅陵县| 平利县| 普兰店市| 淮北市| 大宁县| 连南| 苏尼特左旗| 开封市| 香港| 灵武市| 华蓥市| 泊头市| 仪陇县| 枞阳县| 河池市| 德令哈市| 泰来县| 克拉玛依市| 乌拉特前旗| 边坝县| 大安市| 九江市| 神农架林区| 曲麻莱县| 大新县| 潜山县| 安塞县| 栾城县| 上林县| 班戈县| 车险|