SpringBoot+Mybatis+PostMan(五):token登陸認證過程二(redis緩存引入)


Springboot+Mybatis+redis+postman項目實戰總目錄*

SpringBoot+Mybatis+PostMan(六):token登陸認證過程三(redis封裝與干掉原來session,避免用戶重復登陸)

番外篇:SpringBoot 用戶注冊時經MD5加密存入數據庫

 

 

第二篇章:用戶角色權限訪問控制

 

SpringBoot+Mybatis+PostMan(七):用戶角色權限訪問控制入門(數據模擬實現,不帶數據庫)

 

SpringBoot+Mybatis+PostMan(八):用戶角色權限訪問控制一(數據庫用戶角色表查詢組合)

 

SpringBoot+Mybatis+PostMan(九):用戶角色權限訪問控制二(加入資源表和資源角色對應表)

 

SpringBoot+Mybatis+PostMan(十):用戶角色權限訪問控制三(禁用session、啟用token並集成redis)

 

 

繼上一篇博文,接着嵌入redis緩存,其實在上一篇博文中,用cookie實現攔截比較的不容易,因為對於postman來說,我們在實現增刪改查的時候已經對每個端口進行了訪問,也都生成了其自己對應的token與cookie中,這樣一來,我們設置的攔截器其實就形同虛設了,這時就需要創建一個全新的緩存用於存儲token,用於存儲redis,同時還要方便於訪問,這樣一來我們自然就想到了redis,這篇博文咱們就來介紹如何將redis嵌入springboot項目,同時實現token認證與登陸。

項目代碼獲取地址:https://github.com/yeyuting-1314/testdemo_redis_DM5_insert_page_token.git

一、 准備工作

需要的安裝工具見網盤連接:

鏈接:https://pan.baidu.com/s/1Pkdnn8kfu6SZESEfYqFWkQ
提取碼:nsdj 

1. 首先時redis的安裝和配置,這里我們之前有寫了十分詳細的介紹,詳情借鑒博文:https://www.cnblogs.com/yeyuting/p/14206888.html

2. redis安裝好了后,為方便我們自己看redis緩存中中有哪些數據,我們安裝一個redis可視化工具,安裝包見上面的網頁鏈接。

可視化工具安裝步驟很簡單,一直下一步即可,最后進入redis可視化頁面,在“用戶名”處填入“localhost”,測試一下連接,成功。

 

 

 二、准備工作准備完畢,接下來接着前面代碼繼續修改。

1. 導入redis依賴

<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

2.常量Constants類添加兩個常量

/*
    * redis存儲token設置的過期時間
    * */
    public static final Integer TOKEN_EXPIRE_TIME =60*2 ;
    /*
     * 設置可以重置token過期時間的時間界限
     * */
    public static final Integer TOKEN_RESET_TIME =1000*100 ;

3. 攔截器也要進行相關改進

@Override
    public boolean preHandle (HttpServletRequest request ,
                              HttpServletResponse response , Object o )throws Exception{
        //黑名單  有token  沒有token
        //從request請求頭里面獲取
       // String token = tokenUtil.getToken(request) ; //檢查請求中是否存在token , 如果不存在就直接跳轉到登陸頁面
        String token = request.getHeader("token") ;
        Jedis jedis = new Jedis("localhost" , 6379) ;

        if(StringUtil.isEmpty(token)){
            System.out.println("不存在token");
            response.sendRedirect("/login");
            return false ;
        }
        String username = "" ;
        username = jedis.get(token) ;
        System.out.println("redis中用戶信息值為:" + jedis.get(token));

        if(username != null && !username.trim().equals("")){
            System.out.println("token值匹配成功!");
            Long tokenBirthTime = Long.valueOf(jedis.get(username+token)) ;
            Long diff = System.currentTimeMillis() - tokenBirthTime ;
            if (diff > Constants.TOKEN_RESET_TIME){
                jedis.expire(username , Constants.TOKEN_EXPIRE_TIME) ;
                jedis.expire(token , Constants.TOKEN_EXPIRE_TIME) ;
                System.out.println("token 有效時間成功更新");
                Long newBirthTime =System.currentTimeMillis();
                jedis.set(token+username , newBirthTime.toString()) ;
            }
            return true ;
        }
        response.sendRedirect("/login");
        return false ;

    }

4. controller層增加一個接口

@PostMapping("/loginWithRedis")
    @ResponseBody
    public  Result loginWithRedis(@RequestBody User user){
        Result result = userService.loginWithRedis(user) ;
        return result ;
    }

5. service層

public Result loginWithRedis(User user ) ;
public Result loginWithRedis(User user ){
        User user1 = userMapper.selectByName(user.getUserName()) ;
        if(user1 == null ){
            //response.sendRedirect("/login");
            return Results.failure("用戶不存在,") ;
        }
        if(!user1.getPassword().equals(user.getPassword())){
            return Results.failure("密碼輸入錯誤") ;
        }
        Jedis jedis = new Jedis("localhost" , 6379) ;
        String token = tokenUtil.generateToken(user1) ;
        user1.setToken(token);
        jedis.set(user1.getUserName() , token) ;
        jedis.expire(user1.getUserName() , Constants.TOKEN_EXPIRE_TIME) ;
        jedis.set(token , user1.getUserName()) ;
        jedis.expire(token , Constants.TOKEN_EXPIRE_TIME) ;
        Long currentTime =System.currentTimeMillis() ;
        jedis.set(user1.getUserName()+token , currentTime.toString()) ;
        //用完關閉
        jedis.close();
        System.out.println("redis中token值為:" + jedis.get(user1.getUserName()));
        System.out.println("redis中用戶信息值為:" + jedis.get(token));
        return Results.successWithData(user1) ;
    }

這樣一來,代碼邏輯部分就完成了,接下來是模擬前端部分

三、前端呈現。

 1. 如果對loginWithRedis端口進行攔截設置

攔截設置在MVCConfig類中設置:

@Override
    public void addInterceptors (InterceptorRegistry registry){
       registry.addInterceptor(authenticationInterceptor())
                //表示攔截所有請求
                .addPathPatterns("/*")
                //表示取消對特定路徑的攔截
                .excludePathPatterns("/login")
                .excludePathPatterns("/loginCheck") ;
                //.excludePathPatterns("/loginWithRedis") ;
               //.excludePathPatterns("/selectOne")
                //這里一定不要寫成/**/*.js的形式,spring boot無法識別
                //取消對static目錄下靜態資源的攔截
               // .excludePathPatterns("/static/**") ;
    }

前端模擬:

 

 這時顯示結果是不讓通行,並將其攔截到登陸頁面。

2. 如果不攔截此接口:

攔截設置在MVCConfig類中設置:

 @Override
    public void addInterceptors (InterceptorRegistry registry){
       registry.addInterceptor(authenticationInterceptor())
                //表示攔截所有請求
                .addPathPatterns("/*")
                //表示取消對特定路徑的攔截
                .excludePathPatterns("/login")
                .excludePathPatterns("/loginCheck") 
                .excludePathPatterns("/loginWithRedis") ;
               //.excludePathPatterns("/selectOne")
                //這里一定不要寫成/**/*.js的形式,spring boot無法識別
                //取消對static目錄下靜態資源的攔截
               // .excludePathPatterns("/static/**") ;
    }

前端模擬如上,啟動項目,postman前端顯示如下:

 

 控制台顯示如下:

 

 這時redis可視化界面顯示如下:

 

 這樣一來我們發現redis中已經存儲好了wct對應的token值,將token值記錄下來,下面我們要用此token值進行測試。

3. 在進行一次順利的登陸后,再次攔截此端口,理想情況是用同樣的信息登陸,這次能登陸進去(因為此用戶已經登陸過一次,后面就不會被攔截了,即使我們對此端口進行了攔截,攔截方法中代碼邏輯允許它通過)

攔截設置在MVCConfig類中設置:

@Override
    public void addInterceptors (InterceptorRegistry registry){
       registry.addInterceptor(authenticationInterceptor())
                //表示攔截所有請求
                .addPathPatterns("/*")
                //表示取消對特定路徑的攔截
                .excludePathPatterns("/login")
                .excludePathPatterns("/loginCheck")
                //.excludePathPatterns("/loginWithRedis") ;
               //.excludePathPatterns("/selectOne")
                //這里一定不要寫成/**/*.js的形式,spring boot無法識別
                //取消對static目錄下靜態資源的攔截
               // .excludePathPatterns("/static/**") ;
    }

前端進行模擬實現,在除了body中內容外,還要對header進行token值注入,以為我們在上面一種方法中返回給了前端postman對應的token值,需要前端人員將token值放到header中,但是我們並沒有專門的前端人員進行前端數據處理,這樣一來就需要我們自己手工加入里面,表示我們第一次已經訪問了,並且也生成了token值,這時在攔截的方法中進行前端token值與redis中wct對應的token值匹配,匹配通過就給通過,匹配失敗就攔截下來。

 

 

 

 啟動項目,訪問端口,結果如下:

postman前端顯示:

 

 控制台輸出:

 

 這樣一來,就完成了所有測試,redis也就完整的嵌入到了spring boot項目中。

至此,結束。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM