可能还有很多小伙伴对token概念朦朦胧胧,今天笔者以项目中的用户登录的token验证需求跟大家讲讲其中的来龙去脉,希望能够理清大伙的思路。
这个需求可能早已是老生常谈,但我觉得它永远也不会过时
①谷歌浏览器:login.html---->index.html;
②然后复制index.html的地址在IE浏览器地址栏上,这时普遍网站都会使访问界面直接返回到login.html
只有登录了才可以继续浏览,保证了用户的信息安全性,这个需求就得用到token验证。
①token生成方法
/** * Created by zhangxing on 2017/6/12. */ public class Token { //随机数发生器 public static String genetateToken(){ String token = System.currentTimeMillis()+"";//获得毫秒数加随机数 String tokenMd5=""; try { MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(token.getBytes()); BASE64Encoder base = new BASE64Encoder(); tokenMd5 = base.encode(md5); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return tokenMd5; } public static void main(String args[]){ System.out.println(genetateToken()); } }
②实现后台登录接口
@GetMapping(value = "/login") public Map其中,在实现登录的同时生成token,并将其缓存到session中,Object> getLogin(String loginName,String password){ String zhangxing = Token.genetateToken(); session.setAttribute(SESSION_TOKEN,zhangxing); boolean login = false; //储存token String pwd = loginService.getPassword(loginName); Map ,Object> map = new HashMap , Object>(); if(pwd.equals(password)){ login = true; } map.put("login",login); map.put("token",zhangxing); return map; }
③实现对所有controller拦截
1>拦截类
public class LoginInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 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)){ // 授权路径,不拦截 return true; } else if(null == userToken || "".equals(userToken)) { // 找不到用户Token,重定位到登录 response.sendRedirect(request.getContextPath() + "/login"); return false; } else { // 设置扩展 return true; } } }
继承HandlerInterceptorAdapter,重载preHandler()方法,其中的match()方法是对不进行拦截匹配的资源进行正则匹配,其资源样式为
public static final String NO_MATCH_PATH=".*/(login).*";
逻辑为:
取出session中的用户token,如果token为空就进行拦截;反之放行
2>配置并注册工程的拦截类
@Configuration public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { //拦截所有的controller registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**"); } }
一个注解就能够通知springboot工程,只要符合要求就可以进行拦截匹配
@Configuration
④编写实现前端跳转的controller
@Controller @CrossOrigin public class PageController { @RequestMapping("/login") public String login(){ return "hello"; } @RequestMapping("/success") public String success(){ return "factManage"; } }
return 出来的路径定位到templates中相应的html资源,注意,PageController的上面不要再带上@RequestMapping
⑤看看hello.html的前端代码
html>
charset="utf-8">
token
用户名:type="text" id="username">
密 码:type="text" id="pwd">
只要登录成功了便请求sucess的controller接口
window.location.href ="success";对应的success接口实现
@RequestMapping("/success") public String success(){ return "factManage"; }
效果图:
1>登录
2>成功跳转
3.换IE请求首页http://localhost:8089/success
token显然为空,直接跳到登录界面,这样需求也就实现了,好了,我是张星,欢迎加入博主技术交流群,群号:313145288