流程
- 我们先在后台生成一个token,然后将token返回给前端
- 在拦截器中将跳转页面请求放权
- 前端拿到token后保存到本地浏览器中,然后在每个请求头加入token信息。
登录接口
/**
* 用户登录操作
* @param userEo
* @return
*/
@RequestMapping("/login")
@ResponseBody
public ResponseParam<UserVo> login2(UserEo userEo) {
// 校验用户信息是否正确
UserVo userVo = userService.userLogin(userEo);
if(userVo != null){
// 获得token
String token = JwtUtil.getToken(userEo.getName(), userEo.getPassWord());
if(token != null){
userVo.setToken(token);
return ResponseParam.success(userVo);
}
}
return ResponseParam.error(ErrorCode.CODE_500, "用户名或密码不正确");
}
JWT工具类
package com.guming.library.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @Author:
* @Description: Jwt工具类
* @Date: 10:57 2021/3/31
*/
@Slf4j
public class JwtUtil {
/**
* Token过期时间30分钟
*/
public static final long EXPIRE_TIME = 30 * 60 * 1000;
/**
* 校验 token
* @param token
* @param username
* @param secret 密码等私密信息
* @return
*/
public static boolean verify(String token, String username, String secret) {
try {
// 对密码进行加密,因为我们保存到token中的密码也是用这个方式进行加密的,secret 字符串是未加密传过来的
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm).withClaim("userName", username).build();
DecodedJWT jwt = verifier.verify(token);
return true;
}catch (Exception e){
log.info("校验token失败,原因:"+e);
return false;
}
}
/**
* 生成签名 30分钟过期
* @param username
* @param secret
* @return
*/
public static String getToken(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
// 设置负载内容
.withClaim("userName",username)
// 设置过期时间
.withExpiresAt(date)
// 设置尾部签名信息
.sign(algorithm);
}
/**
* 获得用户名
* @param request
* @return
*/
public static String getUserNameByToken(HttpServletRequest request) {
String token = request.getHeader("token");
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("userName")
.asString();
}
}
拦截器
@Component
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
/**
* 在请求处理之前进行调用(Controller方法调用之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
// 如果不是映射到方法直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
// 自动注入service会失效,需要手动加载需要的service
if(userService == null){
BeanFactory factory = WebApplicationContextUtils
.getRequiredWebApplicationContext(request.getServletContext());
userService = (UserService) factory
.getBean("userService");
}
if (token != null){
String username = JwtUtil.getUserNameByToken(request);
// 这边拿到的 用户名 应该去数据库查询获得密码,简略,步骤在service直接获取密码
try {
boolean result = JwtUtil.verify(token, username, userService.getPasswordByName(username));
if (result) {
return true;
}
}catch (SignatureVerificationException e){
log.info("msg,无效签名");
}catch (Exception e){
log.info("token无效,原因"+e);
}
}
response.sendRedirect(request.getContextPath()+"/user/loginPage");
return false;
/*UserVo user =(UserVo) request.getSession().getAttribute("user");
if(user != null){
request.getSession().setAttribute("user",user);
return true;
}else {
response.sendRedirect(request.getContextPath()+"/user/loginPage");
}
return false;*/
}
前端
登录请求
$.ajax({
async:true,
url:"/user/login",
data:{
name:txtUser,
passWord:txtPwd
},
type:"post",
success:function (data){
if(data.status === 500){
swal("登录失败!", data.message, "error");
}else {
//保存信息到本地,里面都token
localStorage.setItem("user",JSON.stringify(data.result));
window.location.href = "/user/index";
}
},
error:function (data){
swal("登录失败!", data.message, "error");
}
})
}
其他业务请求
var token;
$(function () {
// 获取到我们本地的user信息
var user = localStorage.getItem("user");
var userObj = JSON.parse(user);
token = userObj.token;
});
$.ajax({
async: true,
url: "/borrow/bookDetailed/" + id,
type: "get",
//请求头
headers:{"token":token},
success: function (data) {
window.location.href = "/borrow/bookDetailed/" + id + "";
},
error: function (data) {
swal("操作提示", "跳转失败", "error");
}
})
}