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

基于Redis實現(xiàn)雙加密Token的示例代碼

 更新時間:2025年01月13日 11:38:39   作者:Asthenia0412  
在現(xiàn)代分布式系統(tǒng)中,Token管理是身份驗證和授權的核心部分,本文將深入分析一個基于Redis的Token管理實現(xiàn),探討其設計思路、關鍵代碼邏輯以及實現(xiàn)細節(jié),通過對源碼的逐層剖析,幫助讀者更好地理解Token管理的實現(xiàn)原理,需要的朋友可以參考下

1. 核心設計思路

TokenStore類的核心設計目標是實現(xiàn)一個高效、安全的Token管理系統(tǒng),主要功能包括:

  • Token的生成與存儲:用戶登錄時生成accessTokenrefreshToken,并將其存儲在Redis中。
  • Token的刷新:通過refreshToken獲取新的accessToken。
  • Token的刪除:刪除用戶的所有Token,通常用于用戶注銷或管理員禁用用戶。
  • 用戶信息的獲取:通過accessToken獲取用戶的詳細信息。

為了實現(xiàn)這些功能,TokenStore類依賴Redis作為存儲介質(zhì),利用Redis的高性能和豐富的數(shù)據(jù)結構(如String、Set)來管理Token和用戶信息。

2. 關鍵代碼邏輯分析

2.1 Token的生成與存儲

在用戶登錄時,系統(tǒng)會生成一個accessToken和一個refreshToken,并將它們存儲在Redis中。以下是storeAccessToken方法的核心邏輯:

public TokenInfoBO storeAccessToken(UserInfoInTokenBO userInfoInToken) {
    TokenInfoBO tokenInfoBO = new TokenInfoBO();
    String accessToken = IdUtil.simpleUUID(); // 生成隨機的accessToken
    String refreshToken = IdUtil.simpleUUID(); // 生成隨機的refreshToken

    tokenInfoBO.setUserInfoInToken(userInfoInToken);
    tokenInfoBO.setExpiresIn(getExpiresIn(userInfoInToken.getSysType())); // 設置Token過期時間

    String uidToAccessKeyStr = getUidToAccessKey(getApprovalKey(userInfoInToken)); // 生成uid_to_access的Redis Key
    String accessKeyStr = getAccessKey(accessToken); // 生成access_token的Redis Key
    String refreshToAccessKeyStr = getRefreshToAccessKey(refreshToken); // 生成refresh_to_access的Redis Key

    // 將新的Token加入現(xiàn)有Token列表
    List<String> existsAccessTokens = new ArrayList<>();
    existsAccessTokens.add(accessToken + StrUtil.COLON + refreshToken);

    // 檢查并清理過期的Token
    Long size = redisTemplate.opsForSet().size(uidToAccessKeyStr);
    if (size != null && size != 0) {
        List<String> tokenInfoBoList = stringRedisTemplate.opsForSet().pop(uidToAccessKeyStr, size);
        if (tokenInfoBoList != null) {
            for (String accessTokenWithRefreshToken : tokenInfoBoList) {
                String[] accessTokenWithRefreshTokenArr = accessTokenWithRefreshToken.split(StrUtil.COLON);
                String accessTokenData = accessTokenWithRefreshTokenArr[0];
                if (BooleanUtil.isTrue(stringRedisTemplate.hasKey(getAccessKey(accessTokenData)))) {
                    existsAccessTokens.add(accessTokenWithRefreshToken);
                }
            }
        }
    }

    // 使用Redis管道批量操作
    redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
        long expiresIn = tokenInfoBO.getExpiresIn();

        byte[] uidKey = uidToAccessKeyStr.getBytes(StandardCharsets.UTF_8);
        byte[] refreshKey = refreshToAccessKeyStr.getBytes(StandardCharsets.UTF_8);
        byte[] accessKey = accessKeyStr.getBytes(StandardCharsets.UTF_8);

        // 將Token列表存入Redis
        for (String existsAccessToken : existsAccessTokens) {
            connection.sAdd(uidKey, existsAccessToken.getBytes(StandardCharsets.UTF_8));
        }

        // 設置uid_to_access的過期時間
        connection.expire(uidKey, expiresIn);

        // 存儲refresh_to_access的映射
        connection.setEx(refreshKey, expiresIn, accessToken.getBytes(StandardCharsets.UTF_8));

        // 存儲access_token對應的用戶信息
        connection.setEx(accessKey, expiresIn, Objects.requireNonNull(redisSerializer.serialize(userInfoInToken)));

        return null;
    });

    // 返回加密后的Token
    tokenInfoBO.setAccessToken(encryptToken(accessToken, userInfoInToken.getSysType()));
    tokenInfoBO.setRefreshToken(encryptToken(refreshToken, userInfoInToken.getSysType()));

    return tokenInfoBO;
}

關鍵點分析:

  • Token生成:使用IdUtil.simpleUUID()生成隨機的accessTokenrefreshToken,確保Token的唯一性。
  • Redis數(shù)據(jù)結構
    • uid_to_access:使用Set數(shù)據(jù)結構存儲用戶的所有Token,方便管理和清理。
    • refresh_to_access:使用String數(shù)據(jù)結構存儲refreshTokenaccessToken的映射。
    • access_token:使用String數(shù)據(jù)結構存儲accessToken對應的用戶信息。
  • 過期時間管理:根據(jù)用戶類型(sysType)設置不同的Token過期時間,普通用戶和管理員的Token過期時間不同。
  • Redis管道操作:通過executePipelined方法批量執(zhí)行Redis操作,減少網(wǎng)絡開銷,提升性能。

2.2 Token的刷新

accessToken過期時,用戶可以通過refreshToken獲取新的accessToken。以下是refreshToken方法的核心邏輯:

public ServerResponseEntity<TokenInfoBO> refreshToken(String refreshToken) {
    if (StrUtil.isBlank(refreshToken)) {
        return ServerResponseEntity.showFailMsg("refreshToken is blank");
    }
    ServerResponseEntity<String> decryptTokenEntity = decryptToken(refreshToken); // 解密refreshToken
    if (!decryptTokenEntity.isSuccess()) {
        return ServerResponseEntity.transform(decryptTokenEntity);
    }
    String realRefreshToken = decryptTokenEntity.getData();
    String accessToken = stringRedisTemplate.opsForValue().get(getRefreshToAccessKey(realRefreshToken)); // 獲取對應的accessToken

    if (StrUtil.isBlank(accessToken)) {
        return ServerResponseEntity.showFailMsg("refreshToken 已過期");
    }
    ServerResponseEntity<UserInfoInTokenBO> userInfoByAccessTokenEntity = getUserInfoByAccessToken(accessToken, false);

    if (!userInfoByAccessTokenEntity.isSuccess()) {
        return ServerResponseEntity.showFailMsg("refreshToken 已過期");
    }

    UserInfoInTokenBO userInfoInTokenBO = userInfoByAccessTokenEntity.getData();
    // 刪除舊的refresh_token和access_token
    stringRedisTemplate.delete(getRefreshToAccessKey(realRefreshToken));
    stringRedisTemplate.delete(getAccessKey(accessToken));
    // 生成新的Token
    TokenInfoBO tokenInfoBO = storeAccessToken(userInfoInTokenBO);

    return ServerResponseEntity.success(tokenInfoBO);
}

關鍵點分析:

  • Token解密:通過decryptToken方法解密refreshToken,確保Token的安全性。
  • Token映射:通過refresh_to_access的映射關系,找到對應的accessToken
  • Token清理:刪除舊的refreshTokenaccessToken,防止Token被重復使用。
  • 新Token生成:調(diào)用storeAccessToken方法生成新的Token。

2.3 Token的刪除

在某些情況下(如用戶注銷或管理員禁用用戶),需要刪除用戶的所有Token。以下是deleteAllToken方法的核心邏輯:

public void deleteAllToken(String appId, Long uid) {
    String uidKey = getUidToAccessKey(getApprovalKey(appId, uid)); // 生成uid_to_access的Redis Key
    Long size = redisTemplate.opsForSet().size(uidKey);
    if (size == null || size == 0) {
        return;
    }
    List<String> tokenInfoBoList = stringRedisTemplate.opsForSet().pop(uidKey, size);

    if (CollUtil.isEmpty(tokenInfoBoList)) {
        return;
    }

    // 遍歷并刪除所有Token
    for (String accessTokenWithRefreshToken : tokenInfoBoList) {
        String[] accessTokenWithRefreshTokenArr = accessTokenWithRefreshToken.split(StrUtil.COLON);
        String accessToken = accessTokenWithRefreshTokenArr[0];
        String refreshToken = accessTokenWithRefreshTokenArr[1];
        redisTemplate.delete(getRefreshToAccessKey(refreshToken));
        redisTemplate.delete(getAccessKey(accessToken));
    }
    redisTemplate.delete(uidKey); // 刪除uid_to_access的Key
}

關鍵點分析:

  • 批量刪除:通過uid_to_accessSet數(shù)據(jù)結構,獲取用戶的所有Token并批量刪除。
  • 清理映射關系:刪除refresh_to_accessaccess_token的映射關系,確保Token完全失效。

3. 總結

通過對TokenStore類的深入分析,我們可以看到其設計思路清晰,代碼邏輯嚴謹。通過Redis的高效存儲和豐富的數(shù)據(jù)結構,實現(xiàn)了Token的生成、刷新、刪除以及用戶信息的獲取。這種設計不僅保證了系統(tǒng)的安全性,還提升了系統(tǒng)的性能和可擴展性。

希望本文的源碼分析能夠幫助你更好地理解Token管理的實現(xiàn)原理。

到此這篇關于基于Redis實現(xiàn)雙加密Token的示例代碼的文章就介紹到這了,更多相關Redis雙加密Token內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Win10配置redis服務實現(xiàn)過程詳解

    Win10配置redis服務實現(xiàn)過程詳解

    這篇文章主要介紹了Win10配置redis服務實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Redis?常見緩存問題總結

    Redis?常見緩存問題總結

    這篇文章主要給大家總結了一些Redis?常見緩存問題,并介紹了解決辦法,文中的圖文示例介紹的非常仔細,感興趣的同學可以參考閱讀下
    2023-06-06
  • Redis實現(xiàn)布隆過濾器緩存去重的"智能門衛(wèi)"(實例詳解)

    Redis實現(xiàn)布隆過濾器緩存去重的"智能門衛(wèi)"(實例詳解)

    布隆過濾器(Bloom Filter)本質(zhì)是一個基于哈希函數(shù)的概率型數(shù)據(jù)結構,核心作用是快速判斷一個元素是否存在于集合中,今天給大家介紹Redis實現(xiàn)布隆過濾器緩存去重的"智能門衛(wèi)",感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • 通過redis的腳本lua如何實現(xiàn)搶紅包功能

    通過redis的腳本lua如何實現(xiàn)搶紅包功能

    這篇文章主要給大家介紹了關于通過redis的腳本lua如何實現(xiàn)搶紅包功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-05-05
  • Redis本地/遠程(外部)連接失敗問題及解決

    Redis本地/遠程(外部)連接失敗問題及解決

    這篇文章主要介紹了Redis本地/遠程(外部)連接失敗問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Redis集群刪除后重建后報錯:unrecoverable erro:corrupted cluster config file問題及解決

    Redis集群刪除后重建后報錯:unrecoverable erro:corrupted clust

    這篇文章主要介紹了Redis集群刪除后重建后報錯:unrecoverable erro:corrupted cluster config file問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2026-06-06
  • Windows下搭建Redis集群的方法步驟

    Windows下搭建Redis集群的方法步驟

    本文主要介紹了Windows下搭建Redis集群的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Redis實現(xiàn)訂單過期刪除的方法步驟

    Redis實現(xiàn)訂單過期刪除的方法步驟

    本文主要介紹了Redis實現(xiàn)訂單過期刪除的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • Redis中List實現(xiàn)雙鏈表

    Redis中List實現(xiàn)雙鏈表

    本文主要介紹了Redis中List實現(xiàn)雙鏈表,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • 詳解redis分布式鎖的這些坑

    詳解redis分布式鎖的這些坑

    在很多互聯(lián)網(wǎng)產(chǎn)品應用中,有些場景需要加鎖處理,比如:秒殺,全局遞增ID等等。大部分的解決方案是基于DB實現(xiàn)的,Redis為單進程單線程模式,采用隊列模式將并發(fā)訪問變成串行訪問,且多客戶端對Redis的連接并不存在競爭關系。
    2021-05-05

最新評論

本溪市| 泗水县| 磐安县| 和田市| 论坛| 名山县| 比如县| 岳普湖县| 交城县| 静海县| 陕西省| 东宁县| 来凤县| 虹口区| 四会市| 乐昌市| 烟台市| 深水埗区| 哈密市| 搜索| 罗江县| 乐山市| 滦南县| 方山县| 孙吴县| 安顺市| 杨浦区| 巫溪县| 揭西县| 宁都县| 绥化市| 靖西县| 元氏县| 济阳县| 荣昌县| 屯门区| 长海县| 河南省| 定兴县| 怀集县| 施秉县|