本demo用于测试jwt,通过登录验证通过后,使用jwt生成token,然后在请求header中携带token完成访问用户列表信息。
准备工作:
1. 实体类SysUser.java
packagecom.king.entity;importlombok.Data;
@Datapublic classSysUser {privateString id;privateString username;privateString password;publicSysUser(String username,String password){this.username =username;this.password =password;
}
}
View Code
2. 1 Service方法验证用户账号和密码(这里偷懒没写dao层)
2.2 Service方法获取用户列表
packagecom.king.service;importcom.king.entity.SysUser;importorg.springframework.stereotype.Service;importjava.util.ArrayList;importjava.util.List;
@Servicepublic class SysUserServiceImpl implementsSysUserService{
@Overridepublic booleanlogin(SysUser user) {
String username=user.getUsername();
String password=user.getPassword();if(username.equals("king") && password.equals("123")){return true;
}return false;
}
@Overridepublic ListgetList() {
SysUser user1= new SysUser("king1","12345");
SysUser user2= new SysUser("king2","12345");
SysUser user3= new SysUser("king3","12345");
List list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);returnlist;
}
}
View Code
2.3 Service接口
packagecom.king.service;importcom.king.entity.SysUser;importjava.util.List;public interfaceSysUserService {public booleanlogin(SysUser user);public ListgetList();
}
View Code
重点来了,接下来实现token工具类:
3. 使用jwt完成签名生成方法与验证方法
packagecom.king.util;importcom.auth0.jwt.JWT;importcom.auth0.jwt.JWTVerifier;importcom.auth0.jwt.algorithms.Algorithm;importcom.auth0.jwt.interfaces.DecodedJWT;importcom.king.entity.SysUser;importjava.util.Date;public classTokenUtil {private static final long EXPIRE_TIME= 15*60*1000;private static final String TOKEN_SECRET="token123"; //密钥盐
/*** 签名生成
*@paramuser
*@return
*/
public staticString sign(SysUser user){
String token= null;try{
Date expiresAt= new Date(System.currentTimeMillis() +EXPIRE_TIME);
token=JWT.create()
.withIssuer("auth0")
.withClaim("username", user.getUsername())
.withExpiresAt(expiresAt)//使用了HMAC256加密算法。
.sign(Algorithm.HMAC256(TOKEN_SECRET));
}catch(Exception e){
e.printStackTrace();
}returntoken;
}/*** 签名验证
*@paramtoken
*@return
*/
public static booleanverify(String token){try{
JWTVerifier verifier= JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT jwt=verifier.verify(token);
System.out.println("认证通过:");
System.out.println("issuer: " +jwt.getIssuer());
System.out.println("username: " + jwt.getClaim("username").asString());
System.out.println("过期时间: " +jwt.getExpiresAt());return true;
}catch(Exception e){return false;
}
}
}
4. 添加拦截器
packagecom.king.interceptor;importcom.alibaba.fastjson.JSONObject;importcom.king.util.TokenUtil;importorg.springframework.stereotype.Component;importorg.springframework.web.servlet.HandlerInterceptor;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjava.io.PrintWriter;
@Componentpublic class TokenInterceptor implementsHandlerInterceptor {
@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throwsException{if(request.getMethod().equals("OPTIONS")){
response.setStatus(HttpServletResponse.SC_OK);return true;
}
response.setCharacterEncoding("utf-8");
String token= request.getHeader("admin-token");if(token != null){boolean result =TokenUtil.verify(token);if(result){
System.out.println("通过拦截器");return true;
}
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out= null;try{
JSONObject json= newJSONObject();
json.put("success","false");
json.put("msg","认证失败,未通过拦截器");
json.put("code","50000");
response.getWriter().append(json.toJSONString());
System.out.println("认证失败,未通过拦截器");//response.getWriter().write("50000");
}catch(Exception e){
e.printStackTrace();
response.sendError(500);return false;
}return false;
}
}
View Code
5. 配置拦截器
packagecom.king.config;importcom.king.interceptor.TokenInterceptor;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importjava.util.ArrayList;importjava.util.List;/*** 拦截器配置*/@Configurationpublic class IntercepterConfig implementsWebMvcConfigurer {privateTokenInterceptor tokenInterceptor;//构造方法
publicIntercepterConfig(TokenInterceptor tokenInterceptor){this.tokenInterceptor =tokenInterceptor;
}
@Overridepublic voidaddInterceptors(InterceptorRegistry registry){
List excludePath = new ArrayList<>();
excludePath.add("/user_register"); //注册
excludePath.add("/login"); //登录
excludePath.add("/logout"); //登出
excludePath.add("/static/**"); //静态资源
excludePath.add("/assets/**"); //静态资源
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
}
}
View Code
6. controller层实现登录方法和获取用户列表方法
packagecom.king.controller;importcom.king.entity.SysUser;importcom.king.service.SysUserService;importcom.king.util.TokenUtil;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.List;importjava.util.Map;
@RestControllerpublic classUserController {
@AutowiredprivateSysUserService userService;
@PostMapping(value="/login")
@ResponseBodypublic Maplogin(String username,String password){
Map map = new HashMap<>();
SysUser user= newSysUser(username,password);if(userService.login(user)){
String token=TokenUtil.sign(user);if(token != null){
map.put("code", "10000");
map.put("message", "认证成功");
map.put("token", token);returnmap;
}
}
map.put("code", "0000");
map.put("message", "认证失败");returnmap;
}
@PostMapping(value="/getList")public ListgetList(){
List userList=userService.getList();returnuserList;
}
}
View Code
接下来测试:
1. 使用postman提交登录信息,当密码故意输错时,返回验证失败。
2. 提交正确的用户名和密码,验证通过,可以获取到token信息。
3. 使用token信息放到header中,key设置为admin-token,然后请求用户列表信息。
在后台我们可以看到token携带到用户信息和token的有效时间:
以上为整个jwt的使用流程。