1登录验证,验证成功制作通过JWT制作token,返回token
@PostMapping("login")
@ResponseBody
public String login(UserInfo userInfo, HttpServletRequest request){
UserInfo userInfoExist= userService.login(userInfo);
//1
if(userInfoExist!=null){
//制作token
Map<String, Object> map = new HashMap<>();
map.put("userId",userInfoExist.getId());
map.put("nickName",userInfoExist.getNickName());
System.out.println(request.getRemoteAddr());
// // 如果有 反向代理的话 ,要在反向代理中进行配置 把用户真实ip传递过来
String ipAddr = request.getHeader("X-forwarded-for");
String token = JwtUtil.encode(jwtKey, map, ipAddr);
return token;
} 2前端页面逻辑href=orginUrl+"?token="+token,去认证中心认证,url中携带token。
拦截器逻辑进行拦截,拿到url中的newToken,并写到cookie中,此处可以设置cookie的过期时间定为7天。将userMap中的用户名信息取出来。通过@loginRequire注解决定是否对该url进行拦截,需要拦截的话,如果token不为空,通过HttpClientUtil.doGet(VERIFY_URL + "?token=" + token + "¤tIP=" + currentIP);方法进行验证,如果返回success,则验证成功,并将request的userid设置。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 检查token token可能存在 1 url参数 newToken 2 从cookie中获得 token
String token=null;
//1 newToken的情况
token = request.getParameter("newToken");
if(token !=null){
//把token保存到cookie中
CookieUtil.setCookie(request,response,"token",token, WebConst.cookieMaxAge,false);
}else{
//从cookie中取值 token
token = CookieUtil.getCookieValue(request, "token", false);
}
//如果token 从token中把用户信息取出来
Map userMap=new HashMap();
if(token!=null){
userMap = getUserMapfromToken(token);
String nickName = (String)userMap.get("nickName");
request.setAttribute("nickName",nickName);
}
//判断是否该请求需要用户登录
//取到请求的方法上的注解 LoginRequire
HandlerMethod handlerMethod = (HandlerMethod) handler;
LoginRequire loginRequire = handlerMethod.getMethodAnnotation(LoginRequire.class);
if(loginRequire!=null){
//需要认证
if(token!=null){
// 要把token 发给认证中心进行 认证
String currentIP = request.getHeader("X-forwarded-for");
String result = HttpClientUtil.doGet(VERIFY_URL + "?token=" + token + "¤tIP=" + currentIP);
if("success".equals(result)){ //认证成功
String userId =(String) userMap.get("userId");
request.setAttribute("userId",userId);
return true;
}else if(!loginRequire.autoRedirect()) { //认证失败但是 运行不跳转
return true;
}else { //认证失败 强行跳转
redirect( request, response);
return false;
}
}else { // 强行跳转
// 进行重定向 passport 让用户登录
if(!loginRequire.autoRedirect()) { //认证失败但是 运行不跳转
return true;
}else{
redirect( request, response);
return false;
}
}
}
return true;
} 3其他有@loginRequire请求时,通过拦截器进入认证中心,通过新老token,调用HttpClientUtil.doGet(VERIFY_URL + "?token=" + token + "¤tIP=" + currentIP);进行验证。验证时通过解析token拿到userID,再调用verfify方法验证。verfify方法通过 jedis.exists(userKey),看缓存中是否存在userKey。如果存在再 jedis.expire(userKey,userKey_timeOut)延长缓存过期时间,达到token的时效性。
//http://passport.gmall.com/verify?token=xxxx¤tIP=xxxx
@GetMapping("verify")
@ResponseBody
public String verify(@RequestParam("token") String token, @RequestParam("currentIP") String currentIp){
//1 验证token
Map<String, Object> userMap = JwtUtil.decode(token, jwtKey, currentIp);
//2 验证缓存
if(userMap!=null){//可能是伪造了一个usermap
String userId = (String)userMap.get("userId");
Boolean isLogin= userService.verify(userId);//看看是否有效的userid
if(isLogin){
return "success";
}
}
return "fail";
} 
京公网安备 11010502036488号