首页 > 数据库 >JWT登陆认证+redis实现自动续期

JWT登陆认证+redis实现自动续期

时间:2023-02-09 10:57:13浏览次数:39  
标签:return String JWT redis token import 续期 userTokenDTO public

登陆controller:

package login;

import batch.User;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {
    @Autowired
    User userMapper;
    @Autowired
    RedisServiceImpl redisService;
    @RequestMapping("/login")
    public String login(String username,String password){
        //1.判断用户名密码是否正确
        JSONObject userPO = userMapper.selectUserByName(username);
        if (userPO == null) {
            throw new RuntimeException("用户名不存在");
        }
        if (!password.equals(userPO.get("password"))) {
            throw new RuntimeException("密码错误");
        }

        //2.用户名密码正确生成token
        UserTokenDTO userTokenDTO = new UserTokenDTO();

        userTokenDTO.setId((int)userPO.get("id"));
        userTokenDTO.setCreateTime( System.currentTimeMillis());
        String token = JWTUtil.generateToken(userTokenDTO);

        //3.存入token至redis
        redisService.set(userPO.get("id").toString(), token);
        return token;
    }
@RequestMapping("/loginOut")
    public boolean loginOut(String id) {
        boolean result = redisService.delete(id);
        if (!redisService.delete(id)) {
            throw new RuntimeException("退出登陆出错");
        }

        return result;
    }
@RequestMapping("/updatePassword")
    public String updatePassword(String id,String password) {
        //1.修改密码
        JSONObject user = userMapper.selectUserById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        if (userMapper.updatePassword(id,password) != 1) {
            throw new RuntimeException("密码更新失败");
        }
        //2.生成新的token
        UserTokenDTO userTokenDTO = new UserTokenDTO();
        userTokenDTO.setId(Integer.parseInt(id));
        userTokenDTO.setCreateTime(System.currentTimeMillis());
        userTokenDTO.setPhone(user.get("phone").toString());
        String token = JWTUtil.generateToken(userTokenDTO);
        //3.更新token
        redisService.set(user.get("id").toString(), token);
        return token;
    }
}

UserTokenDTO:

package login;

public class UserTokenDTO {
    private int id;
    private String phone;
    private  long createTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }
}

JWTUtil:

package login;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

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

public class JWTUtil {
    //私钥
    private static final String TOKEN_SECRET = "123456";
/**
     * 生成token,自定义过期时间 毫秒
     *
     * @param userTokenDTO
     * @return
     */
    public static String generateToken(UserTokenDTO userTokenDTO) {

        try {
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");

            return JWT.create()
                    .withHeader(header)
                    .withClaim("token", JSONObject.toJSONString(userTokenDTO))
                    .sign(algorithm);
        } catch (Exception e) {
            System.out.println("generate token occur error");
            return null;
        }
    }

/**
     * 检验token是否正确
     *
     * @param token
     * @return
     */
    public static UserTokenDTO parseToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT jwt = verifier.verify(token);
        String tokenInfo = jwt.getClaim("token").asString();
        return JSON.parseObject(tokenInfo, UserTokenDTO.class);
    }
}

RedisServiceImpl(redis操作的封装类):

package login;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

public final class RedisServiceImpl  {
    /**
     * 过期时长
     */
    private final Long DURATION = 1 * 24 * 60 * 60 * 1000L;

    @Resource
    private RedisTemplate redisTemplate;

    private ValueOperations<String, String> valueOperations;

    @PostConstruct
    public void init() {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setValueSerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
        redisTemplate.setHashValueSerializer(redisSerializer);
        valueOperations = redisTemplate.opsForValue();
    }


    public void set(String key, String value) {
        valueOperations.set(key, value, DURATION, TimeUnit.MILLISECONDS);
        log.info("key={}, value is: {} into redis cache", key, value);
    }


    public String get(String key) {
        String redisValue = valueOperations.get(key);
        log.info("get from redis, value is: {}", redisValue);
        return redisValue;
    }


    public boolean delete(String key) {
        boolean result = redisTemplate.delete(key);
        log.info("delete from redis, key is: {}", key);
        return result;
    }


    public Long getExpireTime(String key) {
        return valueOperations.getOperations().getExpire(key);
    }
}

TokenIntercept(拦截器,验证token是否需要续期):

package login;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;

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

public class TokenIntercept implements HandlerInterceptor {
    @Autowired
    RedisServiceImpl redisService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authToken = request.getHeader("Authorization");
        String token = authToken.substring("Bearer".length() + 1).trim();
        UserTokenDTO userTokenDTO = JWTUtil.parseToken(token);
        //1.判断请求是否有效
        if (redisService.get(String.valueOf(userTokenDTO.getId())) == null
                || !redisService.get(String.valueOf(userTokenDTO.getId())).equals(token)) {
            return false;
        }

        //2.判断是否需要续期
        if (redisService.getExpireTime(String.valueOf(userTokenDTO.getId())) < 1 * 60 * 30) {
            redisService.set(String.valueOf(userTokenDTO.getId()), token);
            System.out.println("update token info, id is:"+userTokenDTO.getId()+"user info is:"+token);
        }
        return true;
    }
}

InterceptorConfig(拦截器配置类,登陆退出不需要走拦截器):

package 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(TokenIntercept())
                .excludePathPatterns("/logout/**")
                .excludePathPatterns("/login/**")
                .addPathPatterns("/**");
    }

    @Bean
    public TokenIntercept TokenIntercept() {
        return new TokenIntercept();
    }
}

 

标签:return,String,JWT,redis,token,import,续期,userTokenDTO,public
From: https://www.cnblogs.com/1--2/p/17104468.html

相关文章

  • 记一次线上事故,redis 的keys问题,cpu引起的性能问题
    公司的一个接口用redis存储pv/uv,一直以来,非常好用,某天发现,接口反映非常慢,经过长时间排查。是redis的cpu非常高,到了60%以上。之前设置的70%报警。然后有个广告使用了keys查......
  • 换nacos得清除redis缓存的原因
    我们公司的项目的nacos导入别的项目的nacos得刷新redis缓存的意思是  后端返回给前端的路由以及后端返回给前端的菜单都存在了redis缓存中,不重新清除redis缓存和浏览器......
  • Redis课程笔记
    Redis安装前台启动后台启动1)备份redis.conf2)修改配置:deamonizeyes3)执行redis-server配置文件的目录key键操作select[dbindex]切换库keys*查所有key......
  • RedisTemplate配置读取序列化
    配置项publicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=newRedi......
  • Redis 异步客户端选型及落地实践
    作者:京东科技王晨Redis异步客户端选型及落地实践可视化服务编排系统是能够通过线上可视化拖拽、配置的方式完成对接口的编排,可在线完成服务的调试、测试,实现业务需求的交付......
  • RedisTemplate序列化
    1.序列化配置publicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=ne......
  • Redis 异步客户端选型及落地实践
    作者:京东科技王晨Redis异步客户端选型及落地实践可视化服务编排系统是能够通过线上可视化拖拽、配置的方式完成对接口的编排,可在线完成服务的调试、测试,实现业务需求的......
  • 8 k8s运行zookeeper和redis等实例
    一Kubernetes实战案例-自定义镜像结合PV/PVC运行Zookeeper集群1构建zookeeper镜像dockfile内容:FROMharbor.magedu.com/magedu/slim_java:8ENVZK_VERSION3.4.14......
  • Redis(十四)——缓存问题
     1、缓存穿透(1)问题描述缓存和数据库中都没有数据。例如利用不存在的key恶意攻击,导致数据库压力过大(2)解决方案接口层增加参数校验,用户鉴权,id非法拦截。从缓存取......
  • java——spring boot集成redis——首先进行复习——本机环境安装(windows环境下)
    鉴于之前学习的时候已经安装完成,此处不重复安装,有需要的可以参考网上各种教程。 本章节以黑马教程为准开始进行复习和学习,进一步提高后端能力 黑马教程:redis——B站......