SoFunction
Updated on 2025-03-05

Sample code for implementing dual encryption tokens based on Redis

1. Core design ideas

TokenStoreThe core design goal of the class is to achieve an efficient and secure Token management system, with its main functions including:

  • Generation and storage of tokens: Generated when the user logs inaccessTokenandrefreshTokenand store it in Redis.
  • Token refresh:passrefreshTokenGet newaccessToken
  • Token's deletion: Delete all tokens of users, which are usually used to log out of users or to disable users by administrators.
  • Obtaining user information:passaccessTokenGet user details.

To achieve these functions,TokenStoreClasses rely on Redis as storage medium, leveraging Redis's high performance and rich data structures (e.g.StringSet) to manage token and user information.

2. Key code logic analysis

2.1 Token generation and storage

When the user logs in, the system generates aaccessTokenAnd onerefreshTokenand store them in Redis. The following isstoreAccessTokenThe core logic of the method:

public TokenInfoBO storeAccessToken(UserInfoInTokenBO userInfoInToken) {
    TokenInfoBO tokenInfoBO = new TokenInfoBO();
    String accessToken = (); // Generate random accessTokens    String refreshToken = (); // Generate random refreshTokens
    (userInfoInToken);
    (getExpiresIn(())); // Set the token expiration time
    String uidToAccessKeyStr = getUidToAccessKey(getApprovalKey(userInfoInToken)); // Generate Redis Key of uid_to_access    String accessKeyStr = getAccessKey(accessToken); // Generate Redis Key to access_token    String refreshToAccessKeyStr = getRefreshToAccessKey(refreshToken); // Generate Redis Key to refresh_to_access
    // Add new tokens to existing token list    List<String> existsAccessTokens = new ArrayList<>();
    (accessToken +  + refreshToken);

    // Check and clean out expired Tokens    Long size = ().size(uidToAccessKeyStr);
    if (size != null && size != 0) {
        List<String> tokenInfoBoList = ().pop(uidToAccessKeyStr, size);
        if (tokenInfoBoList != null) {
            for (String accessTokenWithRefreshToken : tokenInfoBoList) {
                String[] accessTokenWithRefreshTokenArr = ();
                String accessTokenData = accessTokenWithRefreshTokenArr[0];
                if (((getAccessKey(accessTokenData)))) {
                    (accessTokenWithRefreshToken);
                }
            }
        }
    }

    // Batch operation using Redis pipeline    ((RedisCallback<Object>) connection -> {
        long expiresIn = ();

        byte[] uidKey = (StandardCharsets.UTF_8);
        byte[] refreshKey = (StandardCharsets.UTF_8);
        byte[] accessKey = (StandardCharsets.UTF_8);

        // Save the token list into Redis        for (String existsAccessToken : existsAccessTokens) {
            (uidKey, (StandardCharsets.UTF_8));
        }

        // Set the expiration time of uid_to_access        (uidKey, expiresIn);

        // Storing the mapping of refresh_to_access        (refreshKey, expiresIn, (StandardCharsets.UTF_8));

        //Storing user information corresponding to access_token        (accessKey, expiresIn, ((userInfoInToken)));

        return null;
    });

    // Return to the encrypted token    (encryptToken(accessToken, ()));
    (encryptToken(refreshToken, ()));

    return tokenInfoBO;
}

Key points analysis:

  • Token generation:use()Generate randomaccessTokenandrefreshToken, ensure the uniqueness of the token.
  • Redis data structure
    • uid_to_access:useSetThe data structure stores all the user's tokens for easy management and cleaning.
    • refresh_to_access:useStringData structure storagerefreshTokenarriveaccessTokenmap of .
    • access_token:useStringData structure storageaccessTokenCorresponding user information.
  • Expiration time management: According to user type (sysType) Set different token expiration times, and the token expiration times of ordinary users and administrators are different.
  • Redis Pipeline Operation:passexecutePipelinedMethods batch-execute Redis operations to reduce network overhead and improve performance.

2.2 Token refresh

whenaccessTokenWhen expired, users can passrefreshTokenGet newaccessToken. The following isrefreshTokenThe core logic of the method:

public ServerResponseEntity<TokenInfoBO> refreshToken(String refreshToken) {
    if ((refreshToken)) {
        return ("refreshToken is blank");
    }
    ServerResponseEntity<String> decryptTokenEntity = decryptToken(refreshToken); // Decrypt refreshToken    if (!()) {
        return (decryptTokenEntity);
    }
    String realRefreshToken = ();
    String accessToken = ().get(getRefreshToAccessKey(realRefreshToken)); // Get the corresponding accessToken
    if ((accessToken)) {
        return ("refreshToken expired");
    }
    ServerResponseEntity<UserInfoInTokenBO> userInfoByAccessTokenEntity = getUserInfoByAccessToken(accessToken, false);

    if (!()) {
        return ("refreshToken expired");
    }

    UserInfoInTokenBO userInfoInTokenBO = ();
    // Delete old refresh_token and access_token    (getRefreshToAccessKey(realRefreshToken));
    (getAccessKey(accessToken));
    // Generate a new token    TokenInfoBO tokenInfoBO = storeAccessToken(userInfoInTokenBO);

    return (tokenInfoBO);
}

Key points analysis:

  • Token decryption:passdecryptTokenMethod decryptionrefreshToken, ensure the security of the token.
  • Token mapping:passrefresh_to_accessFind the corresponding mapping relationshipaccessToken
  • Token cleaning: Delete the old onerefreshTokenandaccessToken, prevent tokens from being reused.
  • New Token Generation: CalledstoreAccessTokenMethod generates a new token.

2.3 Deletion of Token

In some cases (such as user logout or administrator disable user), all tokens of users need to be deleted. The following isdeleteAllTokenThe core logic of the method:

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

    if ((tokenInfoBoList)) {
        return;
    }

    // traverse and delete all tokens    for (String accessTokenWithRefreshToken : tokenInfoBoList) {
        String[] accessTokenWithRefreshTokenArr = ();
        String accessToken = accessTokenWithRefreshTokenArr[0];
        String refreshToken = accessTokenWithRefreshTokenArr[1];
        (getRefreshToAccessKey(refreshToken));
        (getAccessKey(accessToken));
    }
    (uidKey); // Delete the Key of uid_to_access}

Key points analysis:

  • Batch Delete:passuid_to_accessofSetData structure, obtain all the tokens of the user and delete them in batches.
  • Clean up mapping relationships:deleterefresh_to_accessandaccess_tokenThe mapping relationship ensures that the token is completely invalid.

3. Summary

ByTokenStoreThrough in-depth analysis of the class, we can see that its design ideas are clear and the code logic is rigorous. Through Redis' efficient storage and rich data structure, the generation, refresh, deletion and acquisition of user information are realized. This design not only ensures the security of the system, but also improves the performance and scalability of the system.

I hope that the source code analysis of this article can help you better understand the implementation principles of Token management.

This is the end of this article about the example code of implementing dual encryption tokens based on Redis. For more related Redis dual encryption token content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!