1.場景還原
可能還有很多小伙伴對token概念朦朦朧朧新症,今天筆者以項目中的用戶登錄的token驗證需求跟大家講講其中的來龍去脈呵哨,希望能夠理清大伙的思路。
2.需求分析
這個需求可能早已是老生常談瑰剃,但我覺得它永遠也不會過時
①谷歌瀏覽器:login.html---->index.html歪沃;
②然后復制index.html的地址在IE瀏覽器地址欄上臣淤,這時普遍網(wǎng)站都會使訪問界面直接返回到login.html
只有登錄了才可以繼續(xù)瀏覽橄霉,保證了用戶的信息安全性,這個需求就得用到token驗證邑蒋。
3.實現(xiàn)方案
①token生成方法
public classToken {
//隨機數(shù)發(fā)生器
public staticStringgenetateToken(){
String token = System.currentTimeMillis()+"";//獲得毫秒數(shù)加隨機數(shù)
String tokenMd5="";
try{
MessageDigest md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(token.getBytes());
BASE64Encoder base =newBASE64Encoder();
tokenMd5 = base.encode(md5);
}catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
returntokenMd5;
}
public static? voidmain(String args[]){
System.out.println(genetateToken());
}
}
②實現(xiàn)后臺登錄接口
@GetMapping(value="/login")publicMapgetLogin(String loginName,String password){? ? String zhangxing = Token.genetateToken();session.setAttribute(SESSION_TOKEN,zhangxing);booleanlogin =false;//儲存tokenString pwd =loginService.getPassword(loginName);Map map =newHashMap();if(pwd.equals(password)){? ? ? ? login =true;}? ? map.put("login",login);map.put("token",zhangxing);returnmap;}
其中姓蜂,在實現(xiàn)登錄的同時生成token按厘,并將其緩存到session中
③實現(xiàn)對所有controller攔截
1>攔截類
public classLoginInterceptorextendsHandlerInterceptorAdapter {@Overridepublic booleanpreHandle(HttpServletRequest request,HttpServletResponse response,Object handler)throwsException { ? ? ? ?String userToken = (String) request.getSession().getAttribute(SESSION_TOKEN);//初始化攔截器,設置不攔截路徑String noMatchPath= Constants.NO_MATCH_PATH;String path=request.getServletPath();System.out.println("資源請求路徑:"+path);if(path.matches(noMatchPath)){//授權(quán)路徑钱慢,不攔截return? true;}else if(null== userToken ||"".equals(userToken)) {//找不到用戶Token逮京,重定位到登錄response.sendRedirect(request.getContextPath() +"/login");return? false;}else{//設置擴展return? true;}? ? }}
繼承HandlerInterceptorAdapter,重載preHandler()方法束莫,其中的match()方法是對不進行攔截匹配的資源進行正則匹配懒棉,其資源樣式為
public static finalStringNO_MATCH_PATH=".*/(login).*";
邏輯為:
取出session中的用戶token览绿,如果token為空就進行攔截策严;反之放行
2>配置并注冊工程的攔截類
@Configurationpublic classCustomWebMvcConfigurerAdapterextendsWebMvcConfigurerAdapter {@Overridepublic voidaddInterceptors(InterceptorRegistry registry) {//攔截所有的controllerregistry.addInterceptor(newLoginInterceptor()).addPathPatterns("/**");}}
一個注解就能夠通知springboot工程,只要符合要求就可以進行攔截匹配
@Configuration
④編寫實現(xiàn)前端跳轉(zhuǎn)的controller
@Controller@CrossOriginpublic classPageController {@RequestMapping("/login")publicStringlogin(){return"hello";}@RequestMapping("/success")publicStringsuccess(){return"factManage";}}
return 出來的路徑定位到templates中相應的html資源饿敲,注意妻导,PageController的上面不要再帶上@RequestMapping
⑤看看hello.html的前端代碼
token用戶名:
密? 碼:
登錄functiongetlogin(){alert($("#username").val());alert($("#pwd").val());$.ajax({type:"get",url:"http://localhost:8089/user/login",data:{"loginName":$("#username").val(),"password":$("#pwd").val()? ? ? ? },xhrFields:{withCredentials:true},beforeSend:function(XMLHttpRequest){? ? ? ? },//請求成功回調(diào)success:function(data,textStatus){alert("進來了");alert(data.login);alert(data.token);if(data.login){localStorage.setItem("token",data.token);window.location.href="success";}? ? ? ? ? ? ? ? ? },complete:function(XMLHttpRequest,textStatus){? ? ? ? ? ? ? ? ? ? },error:function(){alert("請求網(wǎng)絡失敗怀各!倔韭。。渠啤。狐肢。添吗。沥曹。");}? ? });}
只要登錄成功了便請求sucess的controller接口
window.location.href="success";
對應的success接口實現(xiàn)
@RequestMapping("/success")publicStringsuccess(){return"factManage";}
效果圖:
1>登錄
2>成功跳轉(zhuǎn)
3.換IE請求首頁http://localhost:8089/success
token顯然為空,直接跳到登錄界面,這樣需求也就實現(xiàn)了碟联,好了妓美,我是張星,歡迎加入博主技術(shù)交流群鲤孵,群號:313145288
csdn博客鏈接:http://blog.csdn.net/zhangxing52077/article/details/73195565