本demo用于测试jwt,经过登陆验证经过后,使用jwt生成token,而后在请求header中携带token完成访问用户列表信息。java
准备工做:web
1. 实体类SysUser.java算法
package com.king.entity; import lombok.Data; @Data public class SysUser { private String id; private String username; private String password; public SysUser(String username,String password){ this.username = username; this.password = password; } }
2. 1 Service方法验证用户帐号和密码(这里偷懒没写dao层)spring
2.2 Service方法获取用户列表json
package com.king.service; import com.king.entity.SysUser; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class SysUserServiceImpl implements SysUserService{ @Override public boolean login(SysUser user) { String username = user.getUsername(); String password = user.getPassword(); if(username.equals("king") && password.equals("123")){ return true; } return false; } @Override public List<SysUser> getList() { SysUser user1= new SysUser("king1","12345"); SysUser user2 = new SysUser("king2","12345"); SysUser user3 = new SysUser("king3","12345"); List<SysUser> list = new ArrayList<>(); list.add(user1); list.add(user2); list.add(user3); return list; } }
2.3 Service接口app
package com.king.service; import com.king.entity.SysUser; import java.util.List; public interface SysUserService { public boolean login(SysUser user); public List<SysUser> getList(); }
重点来了,接下来实现token工具类:ide
3. 使用jwt完成签名生成方法与验证方法工具
package com.king.util; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import com.king.entity.SysUser; import java.util.Date; public class TokenUtil { private static final long EXPIRE_TIME= 15*60*1000; private static final String TOKEN_SECRET="token123"; //密钥盐 /** * 签名生成 * @param user * @return */ public static String 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(); } return token; } /** * 签名验证 * @param token * @return */ public static boolean verify(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. 添加拦截器post
package com.king.interceptor; import com.alibaba.fastjson.JSONObject; import com.king.util.TokenUtil; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; @Component public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{ 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 = new JSONObject(); 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; } }
5. 配置拦截器测试
package com.king.config; import com.king.interceptor.TokenInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.ArrayList; import java.util.List; /** * 拦截器配置 */ @Configuration public class IntercepterConfig implements WebMvcConfigurer { private TokenInterceptor tokenInterceptor; //构造方法 public IntercepterConfig(TokenInterceptor tokenInterceptor){ this.tokenInterceptor = tokenInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry){ List<String> 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); } }
6. controller层实现登陆方法和获取用户列表方法
package com.king.controller; import com.king.entity.SysUser; import com.king.service.SysUserService; import com.king.util.TokenUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class UserController { @Autowired private SysUserService userService; @PostMapping(value="/login") @ResponseBody public Map<String,Object> login(String username,String password){ Map<String,Object> map = new HashMap<>(); SysUser user = new SysUser(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); return map; } } map.put("code", "0000"); map.put("message", "认证失败"); return map; } @PostMapping(value="/getList") public List<SysUser> getList(){ List userList = userService.getList(); return userList; } }
接下来测试:
1. 使用postman提交登陆信息,当密码故意输错时,返回验证失败。
2. 提交正确的用户名和密码,验证经过,能够获取到token信息。
3. 使用token信息放到header中,key设置为admin-token,而后请求用户列表信息。
在后台咱们能够看到token携带到用户信息和token的有效时间:
以上为整个jwt的使用流程。