CRM项目基于JWT实现Token回传Json给前台登录保持并用redis储存登录信息------CRM项目



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        3.2.2
         
    
    com.Alatus
    NetCRM-server
    0.0.1-SNAPSHOT
    NetCRM-server
    NetCRM-server
    
        17
    
    
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            3.0.3
        

        
            com.auth0
            java-jwt
            4.4.0
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        

        
            com.mysql
            mysql-connector-j
            runtime
        
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter-test
            3.0.3
            test
        
        
            org.springframework.security
            spring-security-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    




    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        3.2.2
         
    
    com.Alatus
    NetCRM-server
    0.0.1-SNAPSHOT
    NetCRM-server
    NetCRM-server
    
        17
    
    
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-security
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            3.0.3
        

        
            com.auth0
            java-jwt
            4.4.0
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        

        
            com.mysql
            mysql-connector-j
            runtime
        
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter-test
            3.0.3
            test
        
        
            org.springframework.security
            spring-security-test
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    


package com.alatus.service;

import java.util.concurrent.TimeUnit;

public interface RedisService {
    void setValue(String key,Object value);
    Object getValue(String key);
    Boolean removeValue(String key);
    Boolean expire(String key, Long timeOut, TimeUnit timeUnit);
}
package com.alatus.service;

import java.util.concurrent.TimeUnit;

public interface RedisService {
    void setValue(String key,Object value);
    Object getValue(String key);
    Boolean removeValue(String key);
    Boolean expire(String key, Long timeOut, TimeUnit timeUnit);
}
package com.alatus.service.impl;

import com.alatus.service.RedisService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisServiceImpl implements RedisService {
//    数据源
    @Resource
    private RedisTemplate redisTemplate;
//        放入数据
    @Override
    public void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key,value);
    }
//取出数据
    @Override
    public Object getValue(String key) {
        return redisTemplate.opsForValue().get(key);
    }
//删除数据
    @Override
    public Boolean removeValue(String key) {
        return redisTemplate.delete(key);
    }

    @Override
    public Boolean expire(String key, Long timeOut, TimeUnit timeUnit) {
        return redisTemplate.expire(key,timeOut,timeUnit);
    }
}
package com.alatus.service.impl;

import com.alatus.service.RedisService;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisServiceImpl implements RedisService {
//    数据源
    @Resource
    private RedisTemplate redisTemplate;
//        放入数据
    @Override
    public void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key,value);
    }
//取出数据
    @Override
    public Object getValue(String key) {
        return redisTemplate.opsForValue().get(key);
    }
//删除数据
    @Override
    public Boolean removeValue(String key) {
        return redisTemplate.delete(key);
    }

    @Override
    public Boolean expire(String key, Long timeOut, TimeUnit timeUnit) {
        return redisTemplate.expire(key,timeOut,timeUnit);
    }
}
package com.alatus.constant;

public class Constants {
    public static final String LOGIN_URL = "/api/login";
//    redis的key命名规范,项目名:模块名:功能名:唯一业务参数(比如用户ID)
    public static final String REDIS_JWT_KEY = "crmSystem:user:login:";
//    七天时间
    public static final Long EXPIRE_TIME = 7 * 24 * 60 * 60L;
//    三十分钟
    public static final Long DEFAULT_EXPIRE_TIME = 30 * 60L;
}
package com.alatus.constant;

public class Constants {
    public static final String LOGIN_URL = "/api/login";
//    redis的key命名规范,项目名:模块名:功能名:唯一业务参数(比如用户ID)
    public static final String REDIS_JWT_KEY = "crmSystem:user:login:";
//    七天时间
    public static final Long EXPIRE_TIME = 7 * 24 * 60 * 60L;
//    三十分钟
    public static final Long DEFAULT_EXPIRE_TIME = 30 * 60L;
}
package com.alatus.util;

import com.alatus.model.TUser;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

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

/**
 * jwt的工具类
 *
 */
public class JWTUtils {
    private static final String SECRET = "dYB300olWQ3345;ld<3w48";
    /**
     * 生成jwt
     *
     * @return
     */
    public static String createJWT(String userJSON) {
        //组装头数据
        Map header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        //链式编程
        return JWT.create()
                //头部
                .withHeader(header)

                //负载(可以有多个)
                .withClaim("user", userJSON)

                //签名
                .sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 验证jwt
     *
     */
    public static Boolean verifyJWT(String jwt) {
        try {
            // 使用密钥创建一个jwt验证器
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

            //jwt验证器验证jwt
            jwtVerifier.verify(jwt); //如果此行代码没有抛出异常,就说明jwt验证通过,抛出异常,就说明jwt验证不通过

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

    /**
     * 解析jwt
     *
     */
    public static String parseJWT(String jwt) {
        Map map = new HashMap<>();
        try {
            // 使用密钥创建一个jwt验证器对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

            //jwt验证器对象验证jwt,得到一个解码后的jwt对象
            DecodedJWT decodedJWT = jwtVerifier.verify(jwt);

            //验证通过了,就开始解析负载里面的数据
            Claim userJSON = decodedJWT.getClaim("user");

            return userJSON.asString();
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 解析jwt得到userId
     *
     * @param jwt
     * @return
     */
    public static Integer parseJWTByUserId(String jwt) {
        String userJSON = parseJWT(jwt);
        TUser user = JSONUtils.toBean(userJSON, TUser.class);
        return user.getId();
    }

    /**
     * 解析jwt得到userRole
     *
     * @param jwt
     * @return
     */
    public static List parseJWTByUserRole(String jwt) {
        String userJSON = parseJWT(jwt);
        TUser user = JSONUtils.toBean(userJSON, TUser.class);
        return null;
    }
}
package com.alatus.util;

import com.alatus.model.TUser;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

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

/**
 * jwt的工具类
 *
 */
public class JWTUtils {
    private static final String SECRET = "dYB300olWQ3345;ld<3w48";
    /**
     * 生成jwt
     *
     * @return
     */
    public static String createJWT(String userJSON) {
        //组装头数据
        Map header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        //链式编程
        return JWT.create()
                //头部
                .withHeader(header)

                //负载(可以有多个)
                .withClaim("user", userJSON)

                //签名
                .sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 验证jwt
     *
     */
    public static Boolean verifyJWT(String jwt) {
        try {
            // 使用密钥创建一个jwt验证器
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

            //jwt验证器验证jwt
            jwtVerifier.verify(jwt); //如果此行代码没有抛出异常,就说明jwt验证通过,抛出异常,就说明jwt验证不通过

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

    /**
     * 解析jwt
     *
     */
    public static String parseJWT(String jwt) {
        Map map = new HashMap<>();
        try {
            // 使用密钥创建一个jwt验证器对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

            //jwt验证器对象验证jwt,得到一个解码后的jwt对象
            DecodedJWT decodedJWT = jwtVerifier.verify(jwt);

            //验证通过了,就开始解析负载里面的数据
            Claim userJSON = decodedJWT.getClaim("user");

            return userJSON.asString();
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 解析jwt得到userId
     *
     * @param jwt
     * @return
     */
    public static Integer parseJWTByUserId(String jwt) {
        String userJSON = parseJWT(jwt);
        TUser user = JSONUtils.toBean(userJSON, TUser.class);
        return user.getId();
    }

    /**
     * 解析jwt得到userRole
     *
     * @param jwt
     * @return
     */
    public static List parseJWTByUserRole(String jwt) {
        String userJSON = parseJWT(jwt);
        TUser user = JSONUtils.toBean(userJSON, TUser.class);
        return null;
    }
}
package com.alatus.config.handler;

import com.alatus.constant.Constants;
import com.alatus.model.TUser;
import com.alatus.result.R;
import com.alatus.service.RedisService;
import com.alatus.util.JSONUtils;
import com.alatus.util.JWTUtils;
import com.alatus.util.ResponseUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Resource
    private RedisService redisService;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //由于禁用了session,我们在登录成功后,需要在服务器保持用户的登录状态,前端下次来访问服务器端的时候,服务器端要知道这个人登录了
        TUser tUser = (TUser) authentication.getPrincipal();
//        登录成功的统一结果
        R result = R.OK(tUser);
//        把R对象转为JSON
        String resultJSON = JSONUtils.toJSON(result);
//        生成jwt
        String jwt = JWTUtils.createJWT(resultJSON);
        String key = Constants.REDIS_JWT_KEY+tUser.getId();
//        写入Redis
        redisService.setValue(key,jwt);
//        设置jwt的过期时间,如果选择了记住我,jwt过期时间为七天,否则是30分钟
        Boolean rememberMe = Boolean.valueOf(request.getParameter("rememberMe"));
        if(rememberMe){
            redisService.expire(key,Constants.EXPIRE_TIME, TimeUnit.SECONDS);
        }
        else{
            redisService.expire(key,Constants.DEFAULT_EXPIRE_TIME,TimeUnit.SECONDS);
        }
//        把R以JSON传回前端
        ResponseUtils.write(response,jwt);
    }
}
package com.alatus.config.handler;

import com.alatus.constant.Constants;
import com.alatus.model.TUser;
import com.alatus.result.R;
import com.alatus.service.RedisService;
import com.alatus.util.JSONUtils;
import com.alatus.util.JWTUtils;
import com.alatus.util.ResponseUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Resource
    private RedisService redisService;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //由于禁用了session,我们在登录成功后,需要在服务器保持用户的登录状态,前端下次来访问服务器端的时候,服务器端要知道这个人登录了
        TUser tUser = (TUser) authentication.getPrincipal();
//        登录成功的统一结果
        R result = R.OK(tUser);
//        把R对象转为JSON
        String resultJSON = JSONUtils.toJSON(result);
//        生成jwt
        String jwt = JWTUtils.createJWT(resultJSON);
        String key = Constants.REDIS_JWT_KEY+tUser.getId();
//        写入Redis
        redisService.setValue(key,jwt);
//        设置jwt的过期时间,如果选择了记住我,jwt过期时间为七天,否则是30分钟
        Boolean rememberMe = Boolean.valueOf(request.getParameter("rememberMe"));
        if(rememberMe){
            redisService.expire(key,Constants.EXPIRE_TIME, TimeUnit.SECONDS);
        }
        else{
            redisService.expire(key,Constants.DEFAULT_EXPIRE_TIME,TimeUnit.SECONDS);
        }
//        把R以JSON传回前端
        ResponseUtils.write(response,jwt);
    }
}

你可能感兴趣的:(CRM项目,#,#,Spring-Boot框架,spring,boot,spring,java-ee,java,后端,json,redis)