当前位置: 首页>前端>正文

jwt如何登出把token销毁 java jwt token退出登录

token的登录流程




jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_签名算法,第1张


token是用来验证的一个标识,所以他会在前端登录功能点的时候生成,然后作为一个标识带到后续的功能接口中。所以他的生命周期如上图所示,在登录成功后生成,并且会携带到后续的功能接口中去。

1、前端发送请求登录,后端验证通过,登录成功,同时生成JWT token返回给前端,这样前后端就有了一个统一的信息标识,来表示一个用户的唯一性。

2、前端在接收到这个token后,一般都是存到cookie中,在后续所有接口的调用都会在标头带上token这个参数(下图所示)。后端在除了登录接口外,都会拦截下每一个请求,查看token是不是符合规定(一般是放在缓存中来验证这个token是不是过期/不正确),这样保证信息的准确性。


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_spring_02,第2张


JWT结构

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。

在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串

JWTString=Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)

这里使用这个网站的解析器能够快速解析token jwt解析器


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_签名算法_03,第3张


JWT种类

其实JWT(JSON Web Token)指的是一种规范,这种规范允许我们使用JWT在两个组织之间传递安全可靠的信息,JWT的具体实现可以分为以下几种:

  1. nonsecure JWT:未经过签名,不安全的JWT。其header部分没有指定签名算法
{
  "alg": "none",
  "typ": "JWT"
}
  1. JWS:经过签名的JWT

JWS ,也就是JWT Signature,其结构就是在之前nonsecure JWT的基础上,在头部声明签名算法,并在最后添加上签名。创建签名,是保证jwt不能被他人随意篡改。我们通常使用的JWT一般都是JWS

到目前为止,jwt的签名算法有三种:

  • HMAC【哈希消息验证码(对称)】:HS256/HS384/HS512
  • RSASSA【RSA签名算法(非对称)】(RS256/RS384/RS512)
  • ECDSA【椭圆曲线数据签名算法(非对称)】(ES256/ES384/ES512)
  1. JWE:payload部分经过加密的JWT

Java中使用JWT

官网推荐了6个Java使用JWT的开源库,其中比较推荐使用的是java-jwt和jjwt-root

1、java-jwt

首先是依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

然后是你可以把生成token和解析token的方法封装生成一个工具类

public class JwtUtil {
//TODO 签名密钥
        private static final String SECRET = "自己设置的秘钥&%¥#";

        /**
         * 生成token
         * @param payload token携带的信息
         * @return token字符串
         */
        public static String getToken(Map<String,String> payload){
            // 指定token过期时间为7天
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, 7);

            JWTCreator.Builder builder = JWT.create();
            // 构建payload
            payload.forEach((k,v) -> builder.withClaim(k,v));
            // 指定过期时间和签名算法
            String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SECRET));
            return token;
        }


        /**
         * 解析token
         * @param token token字符串
         * @return 解析后的token
         */
        public static DecodedJWT decode(String token){
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            return decodedJWT;
        }
}

然后在一个测试方法里面可以调用

Map<String,String> map=new HashMap<>();
        map.put("name","xxx");
        map.put("password","123");
        map.put("xxx","aaa");
        String token = JwtUtil.getToken(map);
        System.out.println(token);
        DecodedJWT decodedJWT = JwtUtil.decode(token);
        System.out.println(decodedJWT);

然后你的token的过期时间可以存在一个redis里面,这样就可以比对token有没有过期了

一个简易的登录流程

1、在登录验证通过后,给用户生成一个对应的随机token(注意这个token不是指jwt,可以用uuid等算法生成),然后将这个token作为key的一部分,用户信息作为value存入Redis,并设置过期时间,这个过期时间就是登录失效的时间

2、将第1步中生成的随机token作为JWT的payload生成JWT字符串返回给前端

3、前端之后每次请求都在请求头中的Authorization字段中携带JWT字符串

4、后端定义一个拦截器,每次收到前端请求时,都先从请求头中的Authorization字段中取出JWT字符串并进行验证,验证通过后解析出payload中的随机token,然后再用这个随机token得到key,从Redis中获取用户信息,如果能获取到就说明用户已经登录

拦截器,除了login这个登录接口外,别的接口全部拦截住

import org.springframework.context.annotation.Bean;
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) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")             // 拦截所有请求
                .excludePathPatterns("/user/login/**");    //排除登录接口

    }

    @Bean
    public JwtInterceptor jwtInterceptor() {
        return new JwtInterceptor();
    }
}
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



public class JwtInterceptor implements HandlerInterceptor {

    private final static String signature = "user";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 验证payload部分
        if (StrUtil.isEmpty(token)) {
            throw new RuntimeException("无token,请重新登录");
        }
        Claim name;
        name = Jwtutil.decode(token).getClaim("username");
        //这可以去数据库查你的user是不是name对得到,我这里省略
        if ( name == null) {
            throw new RuntimeException("用户不存在,请重新登录");
        }
        try {
            Jwtutil.decode(token);
        } catch (JWTVerificationException e) {
            e.printStackTrace();
            System.out.println("token错误或已过期,请重新登录");
        }
        return true;
    }
}

然后是Controller来验证是不是拦截到了

首先第一个接口是login,登录,这样会生成一个token,接着调用get方法,在postman里面填入这个生成的token,看看是不是会正常执行、不填写token又会怎么样。

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserImpl user;
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String sendTempMsg(){
        String token = user.getToken();
        return token;
    }


    //测试拦截token
    @RequestMapping(value = "/get", method = RequestMethod.POST)
    public String getTest(HttpServletRequest request){
        String token = request.getHeader("token");
        return token;
    }
}

首先是生成这个token


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_spring_04,第4张


然后用这个token去调用get方法


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_字符串_05,第5张


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_java_06,第6张


填入token,正常通过


jwt如何登出把token销毁 java jwt token退出登录,jwt如何登出把token销毁 java jwt token退出登录_spring_07,第7张



https://www.xamrdz.com/web/2fy1960200.html

相关文章: