jjwt的token机制+ThreadLocal,模拟登录

一、什么是jjwt?jwt怎么生成token?

JWT实现token机制_java jwt token_java-zh的博客-CSDN博客

二、什么是ThreadLocal?

ThreadLocal详解-CSDN博客

三、准备的jar

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
         <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.14</version>
        </dependency>

四、代码实现

ThreadLocalUtils工具类


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

/**
 * @author zhong
 * @describe 线程池缓存工具
 * @date 2023/11/16 10:55
 */
public class ThreadLocalUtils {
    private static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

    /**
     * 向ThreadLocal缓存值
     *
     * @param key   要缓存的KEY
     * @param value 要缓存的VALUE
     */
    public static void set(String key, Object value) {
        if (!isCaheIsNull()) {
            threadLocal.get().put(key, value);
        } else {
            Map<String, Object> vmap = new HashMap<>();
            vmap.put(key, value);
            threadLocal.set(vmap);
        }
    }

    /**
     * 从ThreadLocal里获取缓存的值
     *
     * @param key 要获取的数据的KEY
     * @return 要获取的值
     */
    public static Object getCache(String key) {
        Map<String, Object> map = threadLocal.get();
        if (isCaheIsNull()) {
            return null;
        }
        if (map.containsKey(key)) {
            return map.get(key);
        } else {
            return null;
        }
    }

    /**
     * 根据KEY移除缓存里的数据
     *
     * @param key
     */
    public static void removeByKey(String key) {
        if (isCaheIsNull()) {
            return;
        } else {
            threadLocal.get().remove(key);
        }
    }

    /**
     * 移除当前线程缓存
     * 用于释放当前线程threadlocal资源
     */
    public static void remove() {
        threadLocal.remove();
    }

    private static boolean isCaheIsNull() {
        return threadLocal.get() == null;
    }
}

jjwt实现的工具类在上面的文章有写,这里就不写了

实体类

@Data
@Accessors(chain = true)
public class UserTest {

    /**
     * 用户id
     */
    private Long userId;
    /**
     * 用户名称
     */
    private String userName;
    /**
     * 年龄
     */
    private Integer age;

    /**
     * 角色id
     */
    private Integer roleId;
}

拦截器配置

@Configuration
public class LoginConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册TestInterceptor拦截器
        InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);
        registration.addPathPatterns("/**");//所有路径都被拦截
        registration.excludePathPatterns( // 添加不拦截路径
                "/base/getToken"
        );
    }
}
@Component
public class LoginInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(StringUtils.isEmpty(token)){
            return false;
        }
        Map<String, Object> stringObjectMap = JWTUtil.extractInfo(token, "user:login");
        if(CollectionUtils.isEmpty(stringObjectMap)){
            return false;
        }
        UserTest loginUser = new UserTest();
        loginUser.setRoleId((Integer) stringObjectMap.get("roleId"));
        loginUser.setUserId(Long.valueOf(stringObjectMap.get("userId")+""));
        loginUser.setUserName((String) stringObjectMap.get("userName"));
        ThreadLocalUtils.set("userInfo",loginUser);
        //刷新token过期时间
        Date ecpiration = new Date(System.currentTimeMillis() + 6000000L);
        Jwts.builder().setExpiration(ecpiration);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // TODO Auto-generated method stub
    }

}

controller实现

@RestController
@RequestMapping("/base")
public class TestController {

    @GetMapping("/getToken")
    public String getToken() throws Exception {
        UserTest userTest = new UserTest().setUserId(134288L).setUserName("zhong").setAge(10).setRoleId(2);
        //转成map
        Map<String, Object> map = (Map) JSON.parse(JSON.toJSONString(userTest));
        String token = JWTUtil.generateToken(map, "user:login");
        ThreadLocalUtils.set("token", token);
        System.out.println("生成token");
        return token;
    }

    @GetMapping("/checkToken")
    public String checkToken() {
        UserTest userTest = (UserTest) ThreadLocalUtils.getCache("userInfo");
        // 获取完值以后,进行移除
        ThreadLocalUtils.removeByKey("userInfo");
        return JSON.toJSONString(userTest);
    }
}

五、测试

        5.1 生成token

        这里的data信息就是返回的token信息,因为这里配置了代码返回的格式,所以返回的内容在data里面,参考文档:springboot的@RestControllerAdvice作用和捕获自定义异常返回自定义结果案例-CSDN博客

        5.2 token解析

               解析的内容为token加密的内容

猜你喜欢

转载自blog.csdn.net/qq_36138652/article/details/134441107