赞
踩
JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。
它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证;应用场景如用户登录。
JWT详细讲解请见 github:https://github.com/jwtk/jjwt
① 在传统的用户登录认证中,因为http是无状态的,所以都是采用session方式。用户登录成功,服务端会保证一个session,当然会给客户端一个sessionId,客户端会把sessionId保存在cookie中,每次请求都会携带这个sessionId。
cookie+session这种模式通常是保存在内存中,而且服务从单服务到多服务会面临的session共享问题,随着用户量的增多,开销就会越大。而JWT不是这样的,只需要服务端生成token,客户端保存这个token,每次请求携带这个token,服务端认证解析就可。
② JWT方式校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录,验证token更为简单。
三部分:
.
分隔。例如:
KV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiiwiaWF0IjoxNTY1NTk3MDUzLCJleHAiOjE1NjU2MDA2NTN9.afw5WFm-TwZltGWb1Xs6oBEk5QdaLzlHxDM73IOyeKPF_iN1bLvDAlB7UnSu-Z-Zs
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
编写工具类,静态方法,便于调用:
import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import java.util.Calendar; public class JwtUitls { //token超时变量,N(秒)后 public static final int TOKEN_TIMEOUT = 60*60*1; // 密钥 public static final String APP_SECRET = "xxx@#$%^&dong"; //生成token方法:传入用户名、用户ID 作为payload写入,便于后期解析 public static String createToken(int id,String name) { Calendar instance=Calendar.getInstance(); instance.add(Calendar.SECOND,TOKEN_TIMEOUT); String token=JWT.create() .withClaim("uid",id) //payload,写入变量,用户ID .withClaim("uname",name) //payload,写入变量,用户名 .withExpiresAt(instance.getTime()) //设置过期 .sign(Algorithm.HMAC256(APP_SECRET));//签名及算法 return token; } //验证token合法性 public static DecodedJWT verify(String token){ // 此处如果没有出异常,说明传入token合法且未过期 DecodedJWT verify=JWT.require(Algorithm.HMAC256(APP_SECRET)).build().verify(token); return verify; } public static DecodedJWT getTokenInfo(String token){ try { DecodedJWT verify=JWT.require(Algorithm.HMAC256(APP_SECRET)).build().verify(token); return verify; }catch (Exception e){ return null; } } }
import com.auth0.jwt.exceptions.AlgorithmMismatchException; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.fd.demo.Uitls.JwtUitls; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取请求头中传过来的token String token = request.getHeader("X-Token"); Map<String, Object> map = new HashMap<>(); try { //校验token JwtUitls.verify(token); return true;// 放行 令牌正常才会执行到这里 } catch (SignatureVerificationException e) { //无效签名 map.put("msg", "无效签名"); } catch (TokenExpiredException e) { //过期 map.put("msg", "token过期"); } catch (AlgorithmMismatchException e) { //算法不一致 map.put("msg", "算法不一致"); } catch (Exception e) { //token无效 map.put("msg", "无效token..."); } map.put("code", 501); // 把返回的map封装为JSON String json = new ObjectMapper().writeValueAsString(map); //设置响应类型和编码 response.setContentType("application/json;charset=UTF-8"); //返回响应 response.getWriter().println(json); return false; } }
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //添加拦截器方法 传入我们自己的拦截器 这里的拦截器,是使用的JWT定义的拦截器 registry.addInterceptor(new JwtInterceptor()) .addPathPatterns("/**") //拦截规则 所有 .excludePathPatterns("/api/user/login") //例外规则 .excludePathPatterns("/swagger-resources/**") //下面的例外规则,是swagger的 .excludePathPatterns("/webjars/**") .excludePathPatterns("/v2/**") .excludePathPatterns("/swagger-ui.html/**"); } }
//登录逻辑 略。。
//登录验证成功
String token = JwtUitls.createToken(用户id, 用户名);
//返回创建好的token
//....
//获取请求来的token,调用工具类方法
DecodedJWT tokenInfo = JwtUitls.getTokenInfo(token);
if (tokenInfo!=null){
//token中解析payload
Integer uid = tokenInfo.getClaim("uid").asInt();
String uname = tokenInfo.getClaim("uname").asString()
}
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。