赞
踩
JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库。
首先看下JWT的流程图:
身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。
在SpringMVC中使用的步骤:
1.创建JWT工具类
- public class jwtUtil {
-
- private static Logger logger = LoggerFactory.getLogger(jwtUtil.class);
- private static final String SECRET = "你的秘钥";
- private static final long EXPIRATION_TIME = 1 * 24 * 60 * 60 * 1000; //有效期
-
-
- /**
- * HS256加密
- * @return
- * @throws Exception
- */
- public static String createTokenHS256(String subject) throws Exception{
- String token="";
- try {
- long nowMillis = System.currentTimeMillis();
- long expMillis = nowMillis + EXPIRATION_TIME;
- Date exp = new Date(expMillis);
-
- Algorithm algorithm = Algorithm.HMAC256(SECRET);
- token = JWT.create()
- .withSubject(subject)
- .withIssuer("demo")
- .withExpiresAt(exp)
- .sign(algorithm);
- } catch (JWTCreationException exception){
- logger.error("HS256加密异常",exception.getMessage());
- }
- return token;
- }
-
- /**
- * HS256解密
- * @param token
- * @throws Exception
- */
- public static String verifyTokenHS256(String token) throws Exception{
- String subject="";
- try {
- Algorithm algorithm = Algorithm.HMAC256(SECRET);
- JWTVerifier verifier = JWT.require(algorithm)
- .withIssuer("demo")
- .build();
- subject = verifier.verify(token).getSubject();
- } catch (JWTVerificationException exception){
- logger.error("HS256解密异常",exception.getMessage());
- }
- return subject;
- }
- }
2.创建拦截器
- public class TokenInterceptor implements HandlerInterceptor {
-
-
- /**
- * 拦截每个请求
- */
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {
- response.setCharacterEncoding("utf-8");
- String token = request.getParameter("token");
- String userId= request.getParameter("userId");
-
- //token存在
- if(null != token) {
- String subject=jwtUtil.verifyTokenHS256(token);
- if(!StringUtils.isEmpty(subject) && !StringUtils.isEmpty(userId)){
- if(userId.equals(subject)) {
- return true;
- }
- else{
- responseMessage(response, response.getWriter(), "请求未通过");
- return false;
- }
- }
- else{
- responseMessage(response, response.getWriter(), "请求未通过");
- return false;
- }
- }
- else{
- responseMessage(response, response.getWriter(), "请求未通过");
- return false;
- }
- }
-
- /**
- * 请求不通过,返回错误信息给客户端
- * @param response
- * @param out
- * @param responseData
- */
- private void responseMessage(HttpServletResponse response, PrintWriter out, String responseMsg) {
- response.setContentType("application/json; charset=utf-8");
- out.print(responseMsg);
- out.flush();
- out.close();
- }
-
- }
3.在springmvc-servlet.xml中配置拦截器
- <mvc:interceptors>
-
- <mvc:interceptor>
- <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
- <mvc:mapping path="/**" />
- <mvc:exclude-mapping path="/user/register" />
- <mvc:exclude-mapping path="/user/login" />
-
- <bean class="com.demo.interceptor.TokenInterceptor"></bean>
- </mvc:interceptor>
- </mvc:interceptors>
4.登录时调用jwtUtil生成token,并封装进用户对象返回前端,前端调用后台接口带上userId和token即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。