springboot自定义拦截器,校验token

springboot自定义拦截器,校验token,第1张

springboot自定义拦截器,校验token 一、自定义拦截器
package com.example.demo.test;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;

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

public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisService redis;
    @Autowired
    private UserService userService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws IOException {
        String tokenName = "Authorization";
        // 尝试从header中取token
        String token = request.getHeader(tokenName);
        //尝试从参数中取token
        if (StrUtil.isEmpty(token)) {
            token = request.getParameter(tokenName);
        }
        //尝试从cooke
        if (StrUtil.isEmpty(token)) {
            cookie[] cookies = request.getcookies();
            for (cookie cookie : cookies) {
                if (Objects.equals(cookie.getName(), tokenName)) {
                    token = cookie.getValue();
                }
            }
        }
        //如果前端没有携带token返回json数据
        if (StrUtil.isBlank(token)) {
            PrintWriter pw = response.getWriter();
            pw.write(JSON.toJSonString("用户未登录"));
            return false;
        }
        //解析token
        String jwtId = JwtTool.checkJwtToken(token);
        if (jwtId == null) {
            throw new ServiceException(401, "用户未登录");
        }
        //获取用户ID
        String tokenUserId = JwtTool.getUserId(token);
        //token存在,但是redis不存在。要么是失效,要么是强制下线
        JwtInfo jwt = redis.get(RedisKey.getToken(tokenUserId, jwtId));
        if (jwt == null || !jwt.getToken().equals(token)) {
            throw new ServiceException(401, "您当前登录的账号已失效,请重新登录");
        }
        //获取用户ID
        Long userId = jwt.getUserId();
        //查询用户
        User user = userService.selectById(userId);
        //判断用户是否存在
        if (user == null) {
            throw new ServiceException(MsgCode.CODE_UNAUTHORIZED, "用户不存在");
        }
        //根据业务需求增加其他判断条件
        if (user.getStatus() == 1) {
            throw new ServiceException(MsgCode.CODE_UNAUTHORIZED, "用户已禁用!");
        }
        //将登录用户放到ThreadLocal变量变量中,方便业务获取当前登录用户
        CurrentUser currentUser = new CurrentUser();
        currentUser.setId(userId);
        currentUser.setUserName(user.getAccountname());
        currentUser.setNickName(user.getName());
        //当前用户放到ThreadLocal变量变量中
        CurrentUserUtil.set(currentUser);
        return true;
    }
}

涉及其他类

public class CurrentUserUtil {

    private CurrentUserUtil() {
    }

    private static final ThreadLocal CURRENT_USER = new ThreadLocal();

    public static void set(CurrentUser currentUser) {
        CURRENT_USER.set(currentUser);
    }


    public static CurrentUser currentUser() {
        return CURRENT_USER.get();
    }

    public static void remove() {
        CURRENT_USER.remove();
    }
}
package com.example.demo.test;

import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;


@Getter
@Setter
public class CurrentUser implements Serializable {

    private static final long serialVersionUID = -327159787234887122L;

    private Long id;

    private String jwtId;
    
    private String nickName;
    
    private String userName;
    
    private String phone;
    
    private Long deptId;
    
    private String deptName;
    
    private Integer level;
    
    private Integer flag;
    
    private List authorityList;
}
package com.example.demo.test;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class JwtInfo implements java.io.Serializable {
    
    private String jwtId;
    
    private Long userId;
    
    private String token;
}
package com.example.demo.test;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.jwt.JWT;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

public class JwtTool {

    
    private static int expDays = 7;

    
    private static String issuer = "xxxxxx";

    
    private static String key = "xxxxx";

    
    public interface Payload {
        String userId = "userId";
        String jwtId = "jwtId";
    }

    
    public static JwtInfo createJwtToken(Long userId) {
        String jwtId = UUID.randomUUID().toString();
        try {
            String token = JWT.create()
                    .setIssuer(issuer)
                    .setIssuedAt(DateTime.now())
                    .setJWTId(jwtId)
                    .setCharset(Charset.forName("utf-8"))
                    //有效载荷
                    .setPayload(Payload.userId, userId)
                    .setPayload(Payload.jwtId, jwtId)
                    .setKey(key.getBytes("utf-8"))
                    //7天有效期
                    .setExpiresAt(DateUtil.offsetDay(DateUtil.date(), expDays))
                    .sign();
            JwtInfo jwtInfo = new JwtInfo();
            jwtInfo.setUserId(userId);
            jwtInfo.setJwtId(jwtId);
            jwtInfo.setToken(token);
            return jwtInfo;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    
    public static String checkJwtToken(String token) {
        JWT jwt = JWT.of(token);
        //如果验证成功
        boolean status;
        try {
            status = jwt.setKey(key.getBytes("utf-8")).verify();
            if (status) {
                Object jwtId = jwt.getPayload(Payload.jwtId);
                if (jwtId != null) {
                    return jwtId.toString();
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    
    public static String getUserId(String token) {
        JWT jwt = JWT.of(token);
        return jwt.getPayload(Payload.userId).toString();
    }
}
package com.example.demo.test;


public interface RedisKey { 
    
    String TOKEN = "token:%s:%s";

    static String getToken(String id, String jwtId) {
        String format = String.format(TOKEN, id,jwtId);
        return format;
    }
    
}
package com.example.demo.test;



public class ServiceException extends RuntimeException {

    
    private static final long serialVersionUID = 5909435651426033878L;
    private Integer code;

    public ServiceException(String message) {
        super(message);
        this.code = 201;
    }

    public ServiceException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public ServiceException(Throwable cause) {
        super(cause);
    }

    public ServiceException(String message, Throwable cause) {
        super(message, cause);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
package com.example.demo.test;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;

@Getter
@Setter
public class User implements Serializable {
    
    private Long id;
    
    private String name;


    
    @JsonIgnore
    private String password;
    
    
    private String userName;
    
    
    private Date createTime;
}
二、将拦截器加入系统拦截器
package com.example.demo.config;

import com.example.demo.test.LoginInterceptor;
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 WebConfig implements WebMvcConfigurer {

    @Bean
    public LoginInterceptor loginInterceptor() {
        return new LoginInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(
                        "/api/admin/common/user/login/**",
                        "/api/admin/common/user/kaptcha/**"
                );
    }
}
三、系统任何位置获取当前登录用户方式
CurrentUser currentUser = CurrentUserUtil.currentUser();

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5719650.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存