JWT 简介 - 推酷
1. 组成部分:
Header 头部:一般为token类型和加密算法
Payload 负载:一些用户信息和额外的声明数据
Signature 签名:签名需要使用编码后的header和payload以及一个秘钥 (很安全),前两段的结合加密
2:jar包依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
3:jwt加密和解密的工具类
package com.alienlab.news.utils;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
/**
* Created by Msater Zg on 2017/3/13. jwt实现方式
*/
public class JwtUtils {
public static Claims parseJWT(String jsonWebToken, String base64Security) {
try {
Claims claims = Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))
.parseClaimsJws(jsonWebToken).getBody();
return claims;
} catch (Exception ex) {
return null;
}
}
前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)
public static String createJWT(String name, String userId, String role,
String audience, String issuer, long TTLMillis, String base64Security) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//生成签名密钥 就是一个base64加密后的字符串?
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary (base64Security);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm. getJcaName());
JSONObject jsonObject = new JSONObject();
jsonObject.put(“userName”, name);
jsonObject.put(“userLoginName”, userId);
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder().setHeaderParam(“typ”, “JWT”)
.setIssuedAt(now) //创建时间
.setSubject(jsonObject.toString()) //主题,也差不多是个人的一些信息
.setIssuer(issuer) //发送谁
.setAudience(audience) //个人签名
.signWith(signatureAlgorithm, signingKey); //估计是第三段密钥
//添加Token过期时间
if (TTLMillis >= 0) {
//过期时间
long expMillis = nowMillis + TTLMillis;
//现在是什么时间
Date exp = new Date(expMillis);
//系统时间之前的token都是不可以被承认的
builder.setExpiration(exp).setNotBefore(now);
}
//生成JWT
return builder.compact();
}
}
4:使用的条件(该接口允许跨域 cors来配置跨域)
1:cors配置允许跨域
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Msater Zg on 2017/4/3.
*/
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping(“/**”)
.allowedOrigins(“*”)
.allowCredentials(true)
.allowedMethods(“GET”, “POST”, “DELETE”, “PUT”)
.maxAge(3600);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
List<String> list = new ArrayList<>();
list.add(“*”);
corsConfiguration.setAllowedOrigins(list);
corsConfiguration.addAllowedOrigin(“*”); // 1
corsConfiguration.addAllowedHeader(“*”); // 2
corsConfiguration.addAllowedMethod(“*”); // 3
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(“/**”, buildConfig()); // 4
return new CorsFilter(source);
}
}
2:拦截器拦截方法获取token
1:拦截器配置
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by Msater Zg on 2017/4/5.
*拦截器
*/
public class ApiInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(“拦截了”);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(“拦截了”);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(“拦截了”);
}
}
2: 拦截器管理工具
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Created by Msater Zg on 2017/4/5.
*拦截器管理工具
*/
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//多个拦截器组成一个拦截器链
// addPathPatterns用于添加拦截规则
// excludePathPatterns用户排除拦截
registry.addInterceptor(new ApiInterceptor()).addPathPatterns(“/**”); //对来自/user/** 这个链接来的请求进行拦截
super.addInterceptors(registry);
}
}
5:token的发送与获取
ajax为例子:beforeSend:function(request) {
// token,为登陆时获取到
request.setRequestHeader(“token”,token);
},
后台获取:request.getHeader(“token”);
6:token验证机制
1:通过token解密是否成功可以判断token是否正确或者是否过期
2:解密完成,可以对比用户属性或者用户的固定token(缓存中或者放入数据库)