Springboot+Mybatis+redis+postman項目實戰總目錄*
SpringBoot+Mybatis+PostMan(五):token登陸認證過程二(redis緩存引入)
SpringBoot+Mybatis+PostMan(六):token登陸認證過程三(redis封裝與干掉原來session,避免用戶重復登陸)
番外篇:SpringBoot 用戶注冊時經MD5加密存入數據庫
第二篇章:用戶角色權限訪問控制
SpringBoot+Mybatis+PostMan(七):用戶角色權限訪問控制入門(數據模擬實現,不帶數據庫)
SpringBoot+Mybatis+PostMan(八):用戶角色權限訪問控制一(數據庫用戶角色表查詢組合)
SpringBoot+Mybatis+PostMan(九):用戶角色權限訪問控制二(加入資源表和資源角色對應表)
SpringBoot+Mybatis+PostMan(十):用戶角色權限訪問控制三(禁用session、啟用token並集成redis)
當我們訪問某個網站時,我們首先只能進入到登陸頁面,系統其他頁面時訪問不進去的,所以這里需要通過攔截器實現攔截功能,只能對外界暴露注冊和登陸頁面,其余頁面一律攔截住。用戶登陸時將信息傳遞到服務器端,服務器會查詢此用戶在服務器是否有session,如果沒有,那么就將用戶攔截在登陸頁面,如果用戶信息在服務器端時存在的,那么服務器端為其開辟一個session內存,並為其生成一個sessionID。
這里用到的知識有攔截器、token認證等等,接下來就進行token認證過程。
項目代碼獲取地址:https://github.com/yeyuting-1314/testdemo_insert_page_token.git
一、准備工作
1. 首先添加依賴,這里攔截需要用到JWT工具,需要我們手工導入
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
2. 接下來實現token工具類,實現token生成、獲取特定屬性、獲取請求,以及獲取到token。
@Component public class TokenUtil { /* * 生成token * */ public String generateToken(User user){ Date start = new Date() ; long currentTime = System.currentTimeMillis() + 60*60*1000 ; //一小時的有效時間 Date end = new Date(currentTime) ; String token = "" ; token = JWT.create() .withAudience(Integer.toString(user.getId())) .withAudience(user.getUserName()) .withIssuedAt(start) .withExpiresAt(end) .sign(Algorithm.HMAC256(user.getPassword())); return token ; } /* * 獲取指定token中某個屬性值 * */ public static String get(String token , String key){ List<String> list = JWT.decode(token).getAudience() ; String userId = list.get(0) ; return userId ; } /* * 獲取request * */ public static HttpServletRequest getRequest(){ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); return requestAttributes == null ? null : requestAttributes.getRequest() ; } /* * 獲取token * */ public String getToken(HttpServletRequest request) { Cookie[] cookies = request.getCookies() ; for(Cookie c : cookies){ if(c.getName() == "token"){ return c.getValue() ; } } return null ; } }
3. 自定義攔截器類,preHandle這個方法會業務層執行前先行執行,用於檢查該請求是否帶有token,如果有的話就放行,讓其進行token認證,如果沒有的話就攔截住,重定向到登陸頁面(一般這種情況值我們要訪問除了login和loginCheck兩個頁面的其他頁面時,會被攔截住,重定向到登陸頁面,后面會有演示)
//自定義攔截器類 public class AuthenticationInterceptor implements HandlerInterceptor { @Autowired TokenUtil tokenUtil ; @Override public boolean preHandle (HttpServletRequest request , HttpServletResponse response , Object o )throws Exception{ //檢查請求中是否存在token , 如果不存在就直接跳轉到登陸頁面 String token = tokenUtil.getToken(request) ; if(StringUtil.isEmpty(token)){ System.out.println("不存在token"); response.sendRedirect("/login"); return false ; } return true ; } }
4. 攔截器實現,將需要攔截的頁面進行相應攔截
@Configuration public class MVCConfig implements WebMvcConfigurer { @Bean public HandlerInterceptor authenticationInterceptor(){ return new AuthenticationInterceptor(); } /* * 靜態資源映射 * */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/static/") ; } @Override public void addInterceptors (InterceptorRegistry registry){ registry.addInterceptor(authenticationInterceptor()) //表示攔截所有請求 .addPathPatterns("/*") //表示取消對特定路徑的攔截 .excludePathPatterns("/login") .excludePathPatterns("/loginCheck"); //這里一定不要寫成/**/*.js的形式,spring boot無法識別 //取消對static目錄下靜態資源的攔截 // .excludePathPatterns("/static/**") ; } }
二、 這樣一來准備工作就做好了,接下來就是業務層的實現了。
1. controller層實現
@GetMapping("/login") public String test1(){ System.out.println(PropertiesUtil.class.getClassLoader(). getResource("").getPath()); return "登陸界面" ; } @PostMapping("/loginCheck") @ResponseBody public Result login(@RequestBody User user , HttpServletResponse response){ Result result = userService.loginCheck(user , response) ; return result ; }
2. service層
public Result loginCheck(User user , HttpServletResponse response);
public Result loginCheck(User user , HttpServletResponse response){ User user1 = userMapper.selectByName(user.getUserName()) ; if(user1 == null ){ //response.sendRedirect("/login"); return Results.failure("用戶不存在,") ; } if(!user1.getPassword().equals(user.getPassword())){ return Results.failure("密碼輸入錯誤") ; } String token = tokenUtil.generateToken(user1) ; System.out.println("token:" + token); Cookie cookie = new Cookie("token" , token) ; // 設置cookie的作用域:為”/“時,以在webapp文件夾下的所有應用共享cookie cookie.setPath("/"); response.addCookie(cookie); System.out.println("cookie:"+cookie); return Results.success("登陸成功") ; }
這樣一來,業務層代碼邏輯也書寫完畢,接下來利用postman實現前端模擬。
數據庫內容如下:
1. 若訪問除了login和loginCheck外的其他頁面,會被攔截回到登陸頁面。
2. 如果用戶名正確密碼錯誤:
3. 用戶名不存在
4. 用戶名密碼均正確,成功登陸。
這樣一來,token認證登陸這一功能就實現了。
至此,結束。