Jwt入门教程:实战( 三) | 使用Springboot基于拦截器和redis的Jwt判断用户登录以及安全校验 - Go语言中文社区

Jwt入门教程:实战( 三) | 使用Springboot基于拦截器和redis的Jwt判断用户登录以及安全校验



使用Springboot基于拦截器和redis的Jwt判断用户登录以及安全校验


这里简单介绍用户登录解析Jwt token,从请求的session、以及redis中获取我们想要信息,再做具体业务操作。


不熟悉Jwt概念和用法的可以参考前面两篇:

看了前两篇,下面就不多说了,直接贴代码:(代码可能较长,因为附带了redis的配置,继续玩下看。)


首先,准备工作:配置redis(下方redis的代码较长,大家斟酌,需要的可以copy,放在最后)


下面是正文的开始:


1.MVC配置拦截器
/**
 * MVC配置
 */
@Configuration
public class WebMvcConfig implements  WebMvcConfigurer  {
    @Autowired
    private TokenInterceptor tokenInterceptor;//自定义Token拦截器

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");//token拦截
    }
     
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("Content-Type", "Authorization")
                .allowCredentials(false)
                .maxAge(3600);
    }
}


2.拦截器方法:(这里使用了redis)

import com.huangtu.common.util.user.JwtUtilsHelper;
import com.huangtu.config.RedisUtilsTwo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.impl.Base64Codec;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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

/**
 * @author 慌途L
 */
@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {

	//注入redis工具类
    @Autowired
    private RedisUtilsTwo redisUtilsTwo;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try {
            String cookie = request.getHeader("cookie");
            System.out.println(cookie + "n");

            /**
             * accessToken=eyJhbGciOiJIUzUxMiIsImlhdCI6MTU0MzE5OTg4MywiZXhwIjoxNTQzMjE0MjgzfQ.eyJ1c2VyX2lkIjoxMDAxLCJ5c2VyX25hbWUiOiJhZG1pbiIsImlwIjoiMTkyLjE2OC4xMC4yMDMifQ.-qXmphVPtcmO3PLmuQIiFL7khhKiDjwPZvGyxLbyBOkIMdtFJ7whLY0hSabbJwYH9Dcxmhf1tdPKN2jGSP5YBQ; JSESSIONID=6A769332782C0F436510214757C16063
             */
            //token最后还跟了sessionid,去除
            String[] split1 = cookie.split(";");

            /**
             * accessToken=eyJhbGciOiJIUzUxMiIsImlhdCI6MTU0MzE5OTg4MywiZXhwIjoxNTQzMjE0MjgzfQ.eyJ1c2VyX2lkIjoxMDAxLCJ1c2VyX25hbWU5OiJhZG1pbiIsImlwIjoiMTkyLjE2OC4xMC4yMDMifQ.-qXmphVPtcmO3PLmuQIiFL7khhKiDjwPZvGyxLbyBOkIMdtFJ7whLY0hSabbJwYH9Dcxmhf1tdPKN2jGSP5YBQ
             */
            //得到accessToken
            String[] split = split1[0].split("=");
            System.out.println("accessToken"+split[1]);

            //验证token
            String login = verificationToken(split[1]);

            return true;
        } catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }
    /**
     * 验证token
     *
     * @return
     */
    public String verificationToken(String jwt) {
        String[] splitJwt = jwt.split("\.");
        String params = "";
        if (splitJwt.length == 3) {
            //从redis里面拿到当前用户的accessToken进行对比
            String accessToken = redisUtilsTwo.get("accessToken");
            if(StringUtils.isNotBlank(accessToken)){
                if(jwt.equals(accessToken)){
                    System.out.println("token验证通过");

                    String header = splitJwt[0];
                    String payload = splitJwt[1];
                    String signature = splitJwt[2];//带过来的签名
                    System.out.println(Base64Codec.BASE64URL.decodeToString(header));
                    System.out.println(Base64Codec.BASE64URL.decodeToString(payload));

                    //得到user数据--jwt的payload
                    Claims claims = JwtUtilsHelper.accessTonkenDecodePart(jwt);
                    if (!claims.isEmpty() && claims.size()>0) {
                        Jwt jwt1 = JwtUtilsHelper.accessTonkenDecodeAll(jwt);
                        JSONObject jsonObject = JSONObject.fromObject(jwt1.getHeader());
                        long iat = Integer.parseInt(jsonObject.get("iat").toString());
                        long exp = Integer.parseInt(jsonObject.get("exp").toString());

                        //登录时间和过期时间
                        System.out.println(iat+"||||"+exp);
                        if (!JwtUtilsHelper.isTokenExpired(exp)) {//判断token有效性
                            String userId = claims.get("user_id").toString();
                            String userName = claims.get("user_name").toString();
                            String ip = claims.get("ip").toString();
                            System.out.println("userId="+userId);
                            System.out.println("userName="+userName);
                            System.out.println("ip="+ip);
                            if ("169061".equals(userId) && "admin".equals(userName) && "192.168.110.555".equals(ip)) {
                                params = "token有效";//校验成功,数据完全一致
                            } else {
                                params = "用户id或用户名或ip地址有误";
                            }
                        } else {
                            params = "token过期";
                        }
                    } else {
                        params = "token的payload无数据";
                    }
                } else {
                    params = "token被篡改";
                }
            } else{
                params = "用户为登录";
            }
        } else {
            params = "Jwt Token格式错误";
        }
        return params;
    }

}


3.使用Postman请求:(用的是我项目的请求格式,大家随意),这里我放在请求头里面:使用名字cookie

在这里插入图片描述


![在这里插入图片描述](https://img-blog.csdnimg.cn/20181126204008148.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10


4.到这里,基本上就结束了,大家可以在拦截器里面debugger一步步走。

配置文件:

spring:
    redis:
        database: 0
        host: localhost
        port: 6379
        password: 123456     # 密码()
        timeout: 6000  # 连接超时时长(毫秒)
        pool:
            max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
            max-wait: -1      # 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-idle: 10      # 连接池中的最大空闲连接
            min-idle: 5       # 连接池中的最小空闲连接
    cache:
        type: none

JedisPool:

/**
 * @author 慌途L
 */
@Configuration
@EnableCaching
public class RedisConfigTwo extends CachingConfigurerSupport {
    private Logger logger = Logger.getLogger(getClass());
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.database}")
    private int dataBase;

    @Bean
    public JedisPool redisPoolFactory() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password,dataBase);
        return jedisPool;
    }
}

redis工具类:

import org.springframework.stereotype.Component;
import redis.clients.jedis.BinaryClient;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 慌途L
 */
@Component
public class RedisUtilsTwo{
    @Resource
    private JedisPool jedisPool;

    /**
     * 获取数据
     * @param key
     * @return
     */
    public  String get(String key){
        String value=null;
        Jedis jedis=null;
        try{
            jedis=jedisPool.getResource();
            value=jedis.get(key);
        }catch (Exception e){
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        }finally {
            close(jedis);
        }
        return value;
    }


    public  void del(String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.del(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    public  void set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    public  void set(String key, String value, int time) {

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            jedis.expire(key, time);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    public  void hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.hset(key, field, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    /**
     * 获取数据
     *
     * @param key
     * @return
     */
    public  String hget(String key, String field) {

        String value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.hget(key, field);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }

        return value;
    }

    public  void hdel(String key, String field) {

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.hdel(key, field);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    /**
     * 存储REDIS队列 顺序存储
     * @param  key reids键名
     * @param  value 键值
     */
    public  void lpush(String key, String value) {

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.lpush(key, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }

    /**
     * 移除队列中出现第一个数据
     * @param key
     * @param value
     * @return
     */
    public long lrem(String key, String value){
        Jedis jedis = null;
        long l =0 ;
        try{
            jedis = jedisPool.getResource();
            l = jedis.lrem(key,1,value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return l;
    }

    /**
     * 存储REDIS队列 反向存储
     * @param  key reids键名
     * @param  value 键值
     */
    public  long rpush(String key, String value) {
        Jedis jedis = null;
        long flage=0;
        try {
            jedis = jedisPool.getResource();
            flage = jedis.rpush(key, value);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return flage;
    }

    /**
     * 存储REDIS队列 反向存储
     * @param  key reids键名
     * @param  value 键值
     */
    public  long rpush(String key, String value,int seconds) {
        Jedis jedis = null;
        long flage=0;
        try {
            jedis = jedisPool.getResource();
            flage = jedis.rpush(key, value);
            jedis.expire(key, seconds);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace()<
                        
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_25112523/article/details/84386062
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢