Jwt整合springboot

JWT认证原理、流程整合springboot实战应用,前后端分离认证的解决方案!
https://www.bilibili.com/video/BV1i54y1m7cP?p=1
https://blog.csdn.net/qq_41347385/article/details/109624658
https://blog.csdn.net/u014204541/article/details/103906208

1.JwtUtil工具类


package com.example.demo.util;

/**
 * @ClassName JwtUtil
 * @Description TODO
 * @Author Administrator
 * @Date 2021/02/01 15:04:33
 * @Verison 1.0
 */
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import org.apache.commons.lang3.StringUtils;

import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class JwtUtil {
    //过期时间 3天
    private static final long EXPIRE_TIME = 3 * 24 * 60 * 60 * 1000;
    //私钥
    private static final String TOKEN_SECRET = "huiming@7122^$";

    /**
     * 生成签名,15分钟过期
     * 根据内部改造,支持6中类型,Integer,Long,Boolean,Double,String,Date
     * @param map
     * @return
     */
    public static String sign(Map<String,Object> map) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("typ", "jwt");
            // 返回token字符串
            JWTCreator.Builder builder =  JWT.create()
                    .withHeader(header)
                    .withIssuedAt(new Date()) //发证时间
                    .withExpiresAt(date);  //过期时间
//               .sign(algorithm);  //密钥

            map.entrySet().forEach(entry -> {
                if (entry.getValue() instanceof Integer) {
                    builder.withClaim( entry.getKey(),(Integer)entry.getValue());
                } else if (entry.getValue() instanceof Long) {
                    builder.withClaim( entry.getKey(),(Long)entry.getValue());
                } else if (entry.getValue() instanceof Boolean) {

                    builder.withClaim( entry.getKey(),(Boolean) entry.getValue());
                } else if (entry.getValue() instanceof String) {
                    builder.withClaim( entry.getKey(),String.valueOf(entry.getValue()));
                } else if (entry.getValue() instanceof Double) {
                    builder.withClaim( entry.getKey(),(Double)entry.getValue());
                } else if (entry.getValue() instanceof Date) {
                    builder.withClaim( entry.getKey(),(Date)entry.getValue());
                }
            });
            return builder.sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 检验token是否正确
     * @param **token**
     * @return
     */
    public static JWTVerifier verify(String token){

            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return verifier;
    }

    /**
     *获取用户自定义Claim集合
     * @param token
     * @return
     */
    public static Map<String, Claim> getClaims(String token){
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        JWTVerifier verifier = JWT.require(algorithm).build();
        Map<String, Claim> jwt = verifier.verify(token).getClaims();
        return jwt;
    }

    /**
     * 获取过期时间
     * @param token
     * @return
     */
    public static Date getExpiresAt(String token){
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        return  JWT.require(algorithm).build().verify(token).getExpiresAt();
    }

    /**
     * 获取jwt发布时间
     */
    public static Date getIssuedAt(String token){
        Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
        return  JWT.require(algorithm).build().verify(token).getIssuedAt();
    }

    /**
     * 验证token是否失效
     *
     * @param token
     * @return true:过期   false:没过期
     */
    public static boolean isExpired(String token) {
        try {
            final Date expiration = getExpiresAt(token);
            return expiration.before(new Date());
        }catch (TokenExpiredException e) {
            // e.printStackTrace();
            return true;
        }

    }

    /**
     * 直接Base64解密获取header内容
     * @param token
     * @return
     */
    public static String getHeaderByBase64(String token){
        if (StringUtils.isEmpty(token)){
            return null;
        }else {
            byte[] header_byte = Base64.getDecoder().decode(token.split("\\.")[0]);
            String header = new String(header_byte);
            return header;
        }

    }

    /**
     * 直接Base64解密获取payload内容
     * @param token
     * @return
     */
    public static String getPayloadByBase64(String token){

        if (StringUtils.isEmpty(token)){
            return null;
        }else {
            byte[] payload_byte = Base64.getDecoder().decode(token.split("\\.")[1]);
            String payload = new String(payload_byte);
            return payload;
        }

    }


}

2.依赖和数据库

	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.10</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.3</version>
		</dependency>
		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>3.9.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.9</version>
		</dependency>

在这里插入图片描述
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
mapper-locations: classpath:/mybatis/mapper/*.xml
type-aliases-package: com.example.demo.dao

server:
port: 8123
spring:
application:
name: table-server
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: 123456
url: jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=utf8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=Asia/Shanghai
username: root

3. 实现代码

在这里插入图片描述
UserDao.class

@Mapper
public interface UserDAO {
    //直接根据用户名密码登录
    User login(User user);
}

User.class

@Data
@Accessors(chain = true)
public class User {
    private int userid;
    private String name;
    private String password;
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserDAO">
    <select id="login" parameterType="com.example.demo.domain.User" resultType="com.example.demo.domain.User">
        select * from user where name =#{name} and password = #{password};
    </select>
</mapper>

UserController.class

@RestController
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/doLogin")
    public Map<String, Object> login(User user){
        log.info("id 是[{}]", user.getUserid());
        log.info("用户名:[{}]", user.getName());
        log.info("密码:[{}]", user.getPassword());
        Map<String, Object> map = new HashMap<>();
        try{
            User userDB = userService.login(user);
            Map<String,Object> payload = new HashMap<>();
            payload.put("id", userDB.getUserid());
            payload.put("name", userDB.getName());
            String token = JwtUtil.sign(payload);
            map.put("state", true);
            map.put("msg", "认证成功");
            map.put("token", token);
        }catch (Exception e){
            map.put("state", false);
            map.put("msg", e.getMessage());
        }
        return map;

    }
    @PostMapping("/user/test")
    public Map<String,Object> test(String token){
        Map<String, Object> map = new HashMap<>();
        log.info("当前token为:[{}]",token);

           JWTVerifier verify =  JwtUtil.verify(token);
           map.put("state", true);
           map.put("msg", "请求成功");


        return map;

    }


}

过滤器JWTInterceptor.class

public class JWTInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        Map<String, Object> map = new HashMap<>();

        try {
            JWTVerifier verify =  JwtUtil.verify(token);
            map.put("state", true);
            map.put("msg", "请求成功");
        }catch (SignatureGenerationException e){
            e.printStackTrace();
            map.put("msg","无效签名");
        }catch (TokenExpiredException e){
            e.printStackTrace();
            map.put("msg","token过期");
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();
            map.put("msg","token算法不一致");
        }
        catch (Exception e) {
            e.printStackTrace();
            map.put("msg","token无效");
        }
        map.put("state", false); // 设置状态
        // 将map转为json
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

配置过滤器 InterceptorConfig.class

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/doLogin");// 除了登录放行,其他接口都token验证
    }
}

4.测试在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值