JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的
依赖
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.2.0</version> </dependency>
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency>
|
生成JWT
public static String tokencreate(Object de){ Date now=new Date(); long last=now.getTime()+120*1000; Date expir=new Date(last);
JwtBuilder builder= Jwts.builder() .setIssuedAt(now) .setExpiration(expir) .claim("login",de) .signWith(SignatureAlgorithm.HS256,"xianxian"); String token= builder.compact(); return token; }
|
解析JWT
主要解析JWT代码
Claims cl=Jwts.parser().setSigningKey("xianxian").parseClaimsJws(oldtoken).getBody();
|
当JWT错误或者过期时则会报错
@Test public void decrypt() throws JsonProcessingException { String oldtoken="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoie1wiaWRcIjoxLFwibmFtZVwiOlwi5qCI5LiJXCIsXCJiaXJ0aGRhdGVcIjoxNjM4NDk1MzEzNzc0fSIsImlhdCI6MTYzODQ5NTMxMywiZXhwIjoxNjM4NDk4OTEzLCJsb2dpbiI6eyJpZCI6MSwibmFtZSI6IuagiOS4iSIsImJpcnRoZGF0ZSI6MTYzODQ5NTMxMzc3NH19.tQqtSVqgwLFcuuKn1kv_I4B0_ymBY-LUPHz8Z2nPP7U"; Claims cl=Jwts.parser().setSigningKey("xianxian").parseClaimsJws(oldtoken).getBody(); LinkedHashMap lmap= (LinkedHashMap) cl.get("login"); System.out.println(cl.get("login")); System.out.println("id:"+lmap.get("id")); System.out.println("iat:"+cl.get("iat")); System.out.println(cl); System.out.println("sub:"+cl.getSubject()); ObjectMapper obj=new ObjectMapper(); Userdemo us=obj.readValue(cl.getSubject(),Userdemo.class); System.out.println(us); System.out.println(us.getBirthdate()); }
|
跨域和拦截器配置类
package com.it.seckill.config; import com.it.seckill.Interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired LoginInterceptor login;
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET","PUT","DELETE","POST","HEAD","OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(login) .addPathPatterns("/**") .excludePathPatterns("/selogin"); } }
|
拦截器
拦截器不拦截登入 但是会解析请求头
package com.it.seckill.Interceptor;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
@Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String method=request.getMethod(); if(!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("POST")){ return true; } System.out.println("login标志!"); String token=request.getHeader("token"); Claims cl= Jwts.parser().setSigningKey("xianxian").parseClaimsJws(token).getBody(); System.out.println("检查Token:"+token); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } }
|
控制器
登入成功时就会生成token令牌 发送到前台
package com.it.seckill.controller;
@RestController public class SeckillControllerSQL {
@Autowired UserService use;
@Autowired GoodsService gos;
@RequestMapping("/selogin") public JsonResult selogin(String us,String pa){ JsonResult js; User user=new User(); user.setUsname(us); user.setUspass(pa); User usevi=use.login(user); if(usevi!=null){ String token=TokenTools.tokencreate(usevi); js=new JsonResult(200,"登入成功!",token); }else{ js=new JsonResult(500,"登入失败!"); } return js; }
@RequestMapping("/seckillall") public JsonResult seall(){ List lis=gos.seall(); JsonResult js=new JsonResult(200,"成功!",lis); return js; } }
|
前台登入
当登入成功后就会获取token 把token保存到 localStorage中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>登入页</h1> UserName:<input type="text" name="usname" id="na" required/><br /><br /> Password:<input type="password" name="password" id="pwd" required/><br /><br /> <button type="submit" name="">提交</button> </body> <script> $(function(){ $("button").click(function(){ var ac=$("#na").val(); var pa=$("#pwd").val(); var data ={ "us":ac, "pa":pa } $.post("http://127.0.0.1:8090/selogin",data,function(da){ if(da.code == "200"){ localStorage.setItem("mstoken",da.data); $("a").eq(0).text("退出登入"); $(".app").load("main.html"); }else{ alert("登入失败!"); } }) }) }) </script> </html>
|
前台显示内容
加载完界面后 取出存到浏览器的localStorage 发送请求到后台 带一个tonken
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <h1>主页面</h1> <div id="cd1"> <table border="1px" style="text-align: center;"> </table> </div> </body> <script> $(function () { var mstoken=localStorage.getItem("mstoken"); $.ajax({ headers:{ token:mstoken }, url: "http://127.0.0.1:8090/seckillall", type: "POST", success: function (da) { if(da.code=="500"){ alert("服务器错误!"); }else{ var tr="<tr><td>商品名称</td><td>商品数量</td><td>开抢时间</td></tr>"; for(var i=0;i<da.data.length;i++){ tr+="<tr><td>"+da.data[i].name+"</td><td>"+da.data[i].number+"</td><td>"+da.data[i].startTime+"</td></tr>"; } $("#cd1 table").html(tr); } }, }); }); </script> </html>
|