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項目中。
至此,結束。
