本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的使用流程。