Redis實現(xiàn)單設(shè)備登錄的場景分析
在有些場景下,我們希望用戶一個賬號只能登錄一個設(shè)備。
這個時候我們可以用Redis來實現(xiàn)。
原理: 用戶首次登錄時,將用戶信息存入Redis,key是用戶id,value是token。當(dāng)用戶在其他設(shè)備登錄時,會重新生成token,這個時候原先的token已經(jīng)被覆蓋了。所以用戶在訪問需要登錄賬號的操作時,系統(tǒng)會攔截請求判斷token是否存在。當(dāng)然是不存在的,所以我們就實現(xiàn)了單個設(shè)備登錄的需求。
這里只提供大概的樣例。
用戶登錄
@PostMapping("login")
@ApiOperation(value = "用戶登錄",notes = "用戶登錄")
public GraceJSONResult login(@RequestParam String userId,HttpServletRequest request) throws Exception {
    String uToken = UUID.randomUUID().toString();
    //把token存入redis
    redis.set("redis_user_token"+":"+userId,uToken);
    //返回用戶信息,包含token
    return GraceJSONResult.ok(usersVO);
}攔截器
攔截哪些操作需要用戶登錄,在攔截器中實現(xiàn)單設(shè)備登錄。
說明:BaseInfoProperties是共有的代碼,集成這個類就可以直接使用reidis。
public class BaseInfoProperties {
    @Autowired
    public RedisOperator redis;
}說明:GraceException是自定義的拋出異常的類,這里不做展示。
public class UserTokenInterceptor extends BaseInfoProperties implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = request.getHeader("headerUserId");
        String userToken = request.getHeader("headerUserToken");
        // 判斷用戶id和token是否為空
        if(StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)){
            String redisToken=redis.get(REDIS_USER_TOKEN+":"+userId);
            //判斷token是否失效
            if(StringUtils.isBlank(redisToken)){
                GraceException.display(ResponseStatusEnum.UN_LOGIN);
                return false;
            }else {
                //判斷token是否一致,如果不一致,表示用戶在別的手機(jī)端登錄,token被覆蓋了
                if(!redisToken.equalsIgnoreCase(redisToken)){
                    GraceException.display(ResponseStatusEnum.TICKET_INVALID);
                    return false;
                }
            }
        }else {
            // 用戶id和token為空
            GraceException.display(ResponseStatusEnum.UN_LOGIN);
            return false;
        }
        return true;
    }
}
注冊攔截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //要攔截的請求,哪些需要登錄
        registry.addInterceptor(userTokenInterceptor())
                .addPathPatterns("/userInfo/modifyUserInfo")
                .addPathPatterns("/userInfo/modifyImage");
    }
    //用戶未登錄攔截器
    @Bean
    public UserTokenInterceptor userTokenInterceptor() {
       return  new UserTokenInterceptor();
    }
}
到此這篇關(guān)于Redis實現(xiàn)單設(shè)備登錄的文章就介紹到這了,更多相關(guān)redis單設(shè)備登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
 Redis報錯:Could not create server TCP 
這篇文章主要介紹了Redis報錯:Could not create server TCP listening socket 127.0.0.1:6379: bind:解決方法,是安裝與啟動Redis過程中比較常見的問題,需要的朋友可以參考下2023-06-06
 實現(xiàn)在線?+?離線模式進(jìn)行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南
這篇文章主要介紹了實現(xiàn)在線?+?離線模式進(jìn)行遷移?Redis?數(shù)據(jù)實戰(zhàn)指南的相關(guān)資料,需要的朋友可以參考下2023-01-01
 Redis Cluster Pipeline導(dǎo)致的死鎖問題解決
本文主要介紹了Redis Cluster Pipeline導(dǎo)致的死鎖問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10
 Redis基本數(shù)據(jù)類型Zset有序集合常用操作
這篇文章主要為大家介紹了redis基本數(shù)據(jù)類型Zset有序集合常用操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

