项目结构
1、早pom.xml导入maven依赖
<!-- jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
2、服务层
2.1TokenService
@Service
public class TokenService {
/**
* 过期时间5分钟
*/
private static final long EXPIRE_TIME = 5 * 60 * 1000;
public static String getToken(User user) {
// Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
String token="";
token= JWT.create().withAudience(String.valueOf(user.getId())) // 将 user id 保存到 token 里面,作为载荷
.withExpiresAt(DateUtil.offsetMinute(new Date(),5)) //五分钟后token过期
.sign(Algorithm.HMAC256(user.getPassword())); // 以 password 作为 token 的密钥
return token;
}
}
2.2LoginService
@Service
public class LoginService extends ServiceImpl<LoginDao, User> {
public UserDTO login(UserDTO userDTO){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
System.out.println(userDTO.getUsername());
queryWrapper.eq("name",userDTO.getUsername());
queryWrapper.eq("password",userDTO.getPassword());
User one = getOne(queryWrapper);
// System.out.println(one);
if (one != null) {
String token = TokenService.getToken(one);
userDTO.setToken(token);
userDTO.setRole(one.getRole());
userDTO.setStatus("0");
return userDTO;
} else {
userDTO.setStatus("1");
// throw new SecurityException(Constants.CODE_600,"用户名或密码错误");
return userDTO;
}
// return one !=null;
}
}
3、控制层LoginController(配置好mybatis-plus)
@RestController
@RequestMapping("/login")
@ResponseBody
public class LoginController {
@Autowired
LoginService loginService;
@PostMapping("/examin")
public UserDTO loginExamine(@RequestBody UserDTO userDTO){
return loginService.login(userDTO);
}
}
4、前端采用Vue 将后端传过来的数据放到本地存储中
submitForm() {
let username = this.form.username;
let password = this.form.password;
if (this.examin(username,password)) {
request.post("/login/examin",this.form).then( res =>{
var loc = {
username: " ",
password: " ",
token: " ",
status: " "
}
if (res.status=="0") {
// console.log(res);
var user = new Array()
user.push(loc)
this.$message.success("登录成功")
console.log(res);
this.$router.push({path:'/home'})
localStorage.setItem('user',JSON.stringify(res));
}
else{
this.$message.error("登录失败")
}
})
}else{
}
},
examin(username,password){
console.log(username+"___"+password);
if(!username){
this.$message.error("用户名不能为空")
return false;
}else if(!password){
this.$message.error("密码不能为空 ")
return false;
}else {
return true;
}
},
5、前端从本地存储中获取token 并把 token 放到请求头中
let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
console.log(user.token);
//如有需要:注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
// const token = getCookie(user.token);//这里取token之前,你肯定需要先拿到token,存一下
const token = user.token;
// console.log(token);
if(user.token){
// config.params = {'token':token} //如果要求携带在参数中
config.headers.token= token; //如果要求携带在请求头中
}
5、JwInterceptor拦截器拦截token
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
// 执行认证
// 判断有没有token
if(StrUtil.isBlank(token)) {
throw new RuntimeException("401 无Token,请重新登录");
}
// 获取token中的user id
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new RuntimeException("401 Token验证失败");
}
User user = userService.getById(userId);
if (user == null) {
throw new RuntimeException("401 用户不存在,请重新登录");
}
//用户密码加签 验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token); //验证token
} catch (JWTVerificationException e) {
throw new RuntimeException("401 token验证失败 请重新登录");
}
return true;
}
}
6、注册拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// WebMvcConfigurer.super.addInterceptors(registry);
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**")// 拦截所有请求,判断token是否合法 用户是否需要登录
// .excludePathPatterns("**/login","/user/register","**/export","import");
// 哪些是允许通过的接口
.excludePathPatterns("/login/examin","/user/register","**/export","/importUser","/user/add");
}
@Bean
public JwtInterceptor jwtInterceptor(){
return new JwtInterceptor();
}
}
7、UserDTo
@Data
public class UserDTO {
private String username;
private String password;
private String role;
private String token;
private String status;
}