JWT

Posted SmallCuteMonkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JWT相关的知识,希望对你有一定的参考价值。

六、JWT(json Web Token)一个别人封装好的工具类生成相关的token

  1. 用自定义的token生成的时效性不可以进行定义
  2. 安全性较差

6.1生成JWT

  • 添加依赖:

    <!--        jwt生成 -->
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>3.10.3</version>
            </dependency>
    <!--        jjwt生成-->
            <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
    
    

UserServiceimpl生成token:

 HashMap<String,Object> map=new HashMap<>();

                JwtBuilder builder= Jwts.builder();
                String token = builder.setSubject(username)   //主题就是token中携带的数据
                        .setIssuedAt(new Date()) //设置token的生成时间
                        .setId(users.get(0).getUserId() + "") //设置用户的id为tokenid
                        .setClaims(map)                         //map中可以存放用户的角色权限信息
                        .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)) //设置token的过期时间
                        .signWith(SignatureAlgorithm.HS256, "houzhicong") //设置加密的方式
                        .compact();

                //          验证成功

ShopController进行解析Token:

package com.qfedu.fmmall.controller;


import com.qfedu.fmmall.utils.Base64Utils;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin
@Api(value = "提供购物车业务相关的接口",tags = "购物车管理接口")
@RequestMapping("/shopcart")
public class ShopCartController {

    @RequestMapping("/list")
    @ApiImplicitParam(dataType = "string",name = "token",value = "登录的一个标志",required = true)
    public ResultVO shopcartList(String token){
//        校验输入的token看看是否是用户自己登录的token
//        String decode = Base64Utils.decode(token);
        if(token==null){
            return new ResultVO(ResultStatus.NO, "请先登录", null);


        }else {
            JwtParser parser= Jwts.parser();
            parser.setSigningKey("houzhicong");//解析token 必须和生成token时候生成的密码一致

//            如果token正确(密码正确,有效期内) 则正常执行,否则抛出异常
            try{


                Jws<Claims> claimsJws=parser.parseClaimsJws(token);

                Claims body=claimsJws.getBody();//获取token中的用户数据
                String subject=body.getSubject();//获取生成token设置subject
               String v1=body.get("key1",String.class);//获取生成token时存储的Claims的map中的值
                return new ResultVO(ResultStatus.OK, "success", null);

            }catch (Exception e){
                return new ResultVO(ResultStatus.NO, "登录已经过期,请重新登录!!", null);


            }



        }


    }
}

6.2使用拦截器进行拦截

  1. 创建一个CheckTokenInterceptor
  2. 创建一个拦截器的类
6.3.1
package com.qfedu.fmmall.config;

import com.qfedu.fmmall.interceptor.CheckTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
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 {
    @Autowired
    private CheckTokenInterceptor checkTokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CheckTokenInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/**"
                ,"/doc.html"
                ,"/swagger-ui/**");
    }
}

6.3使用请求头进行传递token

前端但凡访问受限资源,都必须携带token请求,token可以通过请求行(params),请求头(header),以及请求体(data)传递,但习惯使用header传递

axios通过请求头传值 里面的参数用Headers 不用Params

axios({
					method:"get",
					url:baseUrl+"shopcart/list",
					Headers:{
						token:this.token,
					}

				}).then(function (res) {
					console.log(res);
				});
			},
			

6.3.1前端会发送预险性请求,需要拦截器进行放行

package com.qfedu.fmmall.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.jsonwebtoken.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Configuration
public class CheckTokenInterceptor implements HandlerInterceptor {
//   打ov 可以看到它的方法


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getParameter("token");

//        System.out.println("token----------");

//        前端会发送预险性请求
        String method = request.getMethod();

        if("options".equalsIgnoreCase(method)){

            return true;
        }

        if(token==null){
//            提示用户进行登录

            PrintWriter out = response.getWriter();
            ResultVO resultVO= new ResultVO(ResultStatus.NO, "请先登录", null);
//         抽出一个方法进行
            doResponse(response,resultVO);


//            拦截
            return  false;

        }else {
//            验证token

            try{

                JwtParser parser= Jwts.parser();
                parser.setSigningKey("houzhicong");
                Jws<Claims> claimsJws=parser.parseClaimsJws(token);
                return true;
            }catch (ExpiredJwtException e){
                ResultVO resultVO= new ResultVO(ResultStatus.NO, "登录过期,请重新登录", null);
                doResponse(response,resultVO);


                return false;
            }
            catch (UnsupportedJwtException e){
                ResultVO resultVO= new ResultVO(ResultStatus.NO, "Token不合法,请自重", null);
                doResponse(response,resultVO);


                return false;
            }

            catch (Exception e){
                ResultVO resultVO= new ResultVO(ResultStatus.NO, "请先登录", null);
                doResponse(response,resultVO);


                return false;
            }





        }

    }

    private void doResponse(HttpServletResponse response,  ResultVO resultVO) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
//        写上Json格式的resultVO
        String s = new ObjectMapper().writeValueAsString(resultVO);
        out.println(s);
        out.flush();
        out.close();


    }
}

以上是关于JWT的主要内容,如果未能解决你的问题,请参考以下文章

OkHttpInterceptor 从 kotlin 拦截器导航到登录片段

AttributeError: ‘str‘ object has no attribute ‘decode‘解决方法

《代码实例》jwt参与用户凭证方式,生成jwt,security整合jwt

放置jwt.sign代码时出现JWT错误

我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核

Jwt 代码在 .NET Core 2 上不起作用