首页 > 其他分享 >springboot 集成jwt 登录 拦截器获取token 解析token放入holder中

springboot 集成jwt 登录 拦截器获取token 解析token放入holder中

时间:2023-11-17 18:00:25浏览次数:36  
标签:拦截器 springboot util token import com public String

一、依赖

 

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>
    </dependencies>

 二、工具类

package com.example.demo.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.example.demo.contant.RequestKeyConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTUtils {

    // token 签名的秘钥,可设置到配置文件中
    private static final String SECRET_KEY = "secretKey:123456";
    // token过期时间
    public static final long TOKEN_EXPIRE_TIME = 7200 * 1000;

    /**
     * 生成jwt
     */
    public static String createJwt(String userId) {
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
        //设置头信息
        HashMap<String, Object> header = new HashMap<>(2);
        header.put("typ", "JWT");
        header.put("alg", "HS256");
        // 生成 token:头部+载荷+签名
        return JWT.create().withHeader(header)
                .withClaim(RequestKeyConstants.USER_ID, userId)
                .withExpiresAt(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME)).sign(algorithm);
    }

    public static Map<String, Claim> parseJwt(String token) {
        Map<String, Claim> claims = null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            claims = jwt.getClaims();
            return claims;
        } catch (Exception e) {
            log.error("jwt token  {} 解析异常",token);
            return null;
        }
    }

    /**
     * 解析jwt
     */
    public static Long getUserId(String token) {
        try {
            Map<String, Claim> claims = parseJwt(token);
            if (claims != null) {
                String userId = claims.get(RequestKeyConstants.USER_ID).asString();
                if (StringUtils.hasLength(userId)) {
                    return Long.valueOf(userId);
                }
            }
        } catch (Exception e) {
            log.error("jwt token  {} 解析异常",token);
        }
        return null;
    }
}

 三、拦截器

package com.example.demo.intercept;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.interfaces.Claim;
import com.example.demo.contant.RequestKeyConstants;
import com.example.demo.util.JWTUtils;
import com.example.demo.util.RequestContext;
import com.example.demo.util.UserLoginContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class RequestProcessInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(!StringUtils.hasLength(token)) {
            token = request.getParameter("token");
        }
        if(!StringUtils.hasLength(token)){
            Map<String,Object> map = new HashMap<>();
            map.put("err",100);
            map.put("msg","请先登录");

            String json = JSONObject.toJSONString(map);
            //设置响应头(告知浏览器:响应的数据类型为json、响应的数据编码表为utf-8)
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);
            return false;//不放行
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)
        try {
            Long userId = JWTUtils.getUserId(token);//获取用户的基本信息

            RequestContext context = UserLoginContextHolder.get() == null ? new RequestContext() : UserLoginContextHolder.get();
            this.setCookies(request, context);
            context.setUserId(Long.valueOf(userId));
            UserLoginContextHolder.set(context);

        }catch (Exception e){
            Map<String,Object> map = new HashMap<>();
            map.put("err",101);
            map.put("msg","token不正确");
            String json = JSONObject.toJSONString(map);
            //设置响应头
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);
            return false;
        }

        //6.放行
        return true;
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        UserLoginContextHolder.remove();
        ThreadContext.clearAll();
    }

    private void setCookies(HttpServletRequest request, RequestContext requestContext) {
        Cookie[] cookies = request.getCookies();
        requestContext.setCookies(cookies);
    }

}
package com.example.demo.contant;

public class RequestKeyConstants {

   public static final String USER_ID="curr_user_id";
}

·当前用户信息承载类

package com.example.demo.util;

import lombok.Data;

import javax.servlet.http.Cookie;

@Data
public class RequestContext {
    private Long userId; //当前用户ID
    private String deviceId; //设备id
    private String deviceType; //设备类型
    private String appVersion; //APP版本
    private String ip;//客户端IP
    private String requestId;
    private Cookie[] cookies;
}
package com.example.demo.util;


public class UserLoginContextHolder {
    private static final InheritableThreadLocal<RequestContext> REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL = new InheritableThreadLocal();

    public UserLoginContextHolder() {
    }

    public static RequestContext get() {
        return (RequestContext)REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.get();
    }

    public static void set(RequestContext context) {
        REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.set(context);
    }

    public static void remove() {
        REQUEST_CONTEXT_INHERITABLE_THREAD_LOCAL.remove();
    }
}
package com.example.demo.config;

import com.example.demo.intercept.RequestProcessInterceptor;
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 WebAppConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestProcessInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login", "/register", "/image/**", "/js/**", "/css/**")
                .order(0);
    }
}
package com.example.demo.controller;

import com.example.demo.util.JWTUtils;
import com.example.demo.util.RequestContext;
import com.example.demo.util.UserLoginContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;

@RestController
@Slf4j
public class LoginController {

    @RequestMapping("/login")
    public String create(@RequestParam("userId") Long userId) {
        String token = JWTUtils.createJwt(userId + "");
        return token;
    }

    @RequestMapping("/auth/parse")
    public RequestContext parse() {
        RequestContext requestContext = UserLoginContextHolder.get();
        Cookie[] cookies = requestContext.getCookies();
        StringBuilder sb = new StringBuilder();
        for (Cookie cookie : cookies) {
           sb.append(cookie.getName());
           sb.append("====");
           sb.append(cookie.getValue());
           sb.append("\r\n");
        }
        log.info(sb.toString());

        return requestContext;
    }
}

 

标签:拦截器,springboot,util,token,import,com,public,String
From: https://www.cnblogs.com/niun/p/17839401.html

相关文章

  • springboot 热部署
    加载插件<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</......
  • 源码解析axios拦截器
    从源码解析axios拦截器是如何工作的axios拦截器的配置方式axios中有两种拦截器:axios.interceptors.request.use(onFulfilled,onRejected,options):配置请求拦截器。onFulfilled方法在发送请求前执行,接收config对象,返回一个新的config对象,可在此方法内修改config对......
  • 实现无感刷新token
    目录需求实现问题解决注意事项:需求当token过期的时候,刷新token,前端需要做到无感刷新token,即刷token时要做到用户无感知,避免频繁登录。实现思路方法一后端返回过期时间,前端判断token过期时间,去调用刷新token接口缺点:需要后端额外提供一个token过期时间的字段;使......
  • springboot学习日记(五)
    今天先安装试用了下postman,get获取自己的网页,返回是网页源码。这里贴一下前几天测试的开源新手项目IncrediableKJ/Student-management-system:基于springboot+mybatis+thymeleaf的学生信息管理系统,适合springboot初学者的练手项目(github.com)然后发现添加学生列表失败,看了......
  • SpringBoot使用@Value获取不到值的问题
    背景在一次SpringBoot项目改造为Cloud的过程中,使用Nacos作为配置中心获取属性,改造后程序启动报错,查看日志,定位到代码:解决方案如果了解Bean的生命周期的同学应该知道,Spring在创建Bean的时候,会使用无参构造函数去初始化一个Bean,@Value这个阶段是属于依赖注入,是在初始化之后的,所......
  • 02_自定义Springboot starter
     创建springbootstarter 创建一个demostarter  创建配置类@Configuration@EnableConfigurationProperties(EmailProperties.class)@ConditionalOnBean(EmailEnable.class)publicclassEmailAutoConfiguration{static{System.out.println("Em......
  • springboot整合前端实现断点续传、大文件秒传以及多线程上传下载
    前端,百度开源框架webuploader新建upload.htmlwebuploader官网地址:http://fex.baidu.com/webuploader/<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>webuploader</title></head><!--引......
  • springboot 集成dubbo 关键配置:
    1.pom<!--dubbo与zk的组件start--><dependency><groupId>com.alibaba.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>0.1.0</version></dependency><dependency>......
  • 通过linux etc/init.d 来执行springboot jar
    今天解开了一个困扰我好久的问题,我们的项目到底是怎么执行的?为什么把项目的jar包scp到服务器,然后再创建一个同名的conf文件,之后建立一个软连接就可以start和stop了?springbootjar和普通jar的区别springbootjar是可执行的不可以被其他项目依赖的普通jar是不可执行的是可以......
  • k8s中,如何通过token的方式,访问认证的kubelet的metrics指标?
     1、背景说明kubelet本身的10250端口,就提供了节点上的监控数据。 metricsserver可以进行访问。 但是,如果想要通过浏览器,或者curl命令进行访问,发现,是需要进行认证  [root@nccztsjb-node-02~]#curl-khttps://172.20.59.238:10250/metricsUnauthorized[root@n......