Skip to content
On this page

JWT Web Token

可以轻松自定义生成自己JWT Web Token.和基于 JWT 的userJwtToken

通过userJwtToken你可以轻松生成基于用户登录认证的Token

java
@Autowired
private UserJwtToken userJwtToken;
@GetMapping("/login")
public Result login() {
    UserEntry userEntry = new UserEntry();
    userEntry.setUserId("2");
    userEntry.setUsername("billy");
    userEntry.setHobby("eat");
    userJwtToken.rememberMe=true;
    String token = userJwtToken.createdToken(userEntry.getUserId(), userEntry.getUsername(), userEntry);
    return Result.buildSuccess(token);
}

解析token获取用户信息

java
@GetMapping("/user")
public Result getUser() {
    String token = "eyJhbGciOiJIUzI1NiIsInppcCI6IkRFRiJ9.eNqqViouTVKyUkrKzMmpVNJRyiwuBvKMgKyskkwoK7WiQMnK0MzC0tTUwsDEWEeptDi1SMmqGkx7pkBVgTh5ibmpSIZl5CclVQL5qYklSrW1AAAAAP__.8nWRs40LbRTIQBhJ8jVaANPcvsmX0zoLR66R-b2Uc4M";
    String userName=userJwtToken.getUserName(token);
    String userId= userJwtToken.getUserId(token);
    UserEntry userEntry=userJwtToken.parseUserToken(token,UserEntry.class);
    return Result.buildSuccess(userId);
}

自定义 Token 秘钥和签名配置

yml
jwt:
  secret: 123456 # 秘钥 建议加密后秘钥如md5 不要使用明文长度大于6位
  expiration: 86400 # token 过期时间(单位秒 1天后过期)
  token-header: Token #header token 名称
  remember-me-expiration: 604800 #记住我 token过期时间(单位秒 7天后过期)
  user-sign: true # 是否自定义签名。为true需要实现加密接口。和 配置 jwtCfg注入对应bean

自定义签名认证和动态秘钥授权需要实现UserSign接口配置UserJwtConfig配置类注入自定义签名bean

也可以继承UserSignWith默认实现类重写对应签名和秘钥方法。建议使用此种

java
package cn.soboys.superaide.config;

import cn.soboys.restapispringbootstarter.authorization.UserSign;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/7/16 00:20
 * @webSite https://github.com/coder-amiao
 */
public class MyUserSign implements UserSign {

    @Override
    public SignatureAlgorithm sign() {
        return SignatureAlgorithm.HS256;
    }

    @Override
    public String AuthKey() {
        return null;
    }
}

AuthKey 返回null时候会使用你在属性文件配置的秘钥。没有会使用默认的

java
package cn.soboys.superaide.config;

import cn.soboys.restapispringbootstarter.authorization.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/7/15 09:49
 * @webSite https://github.com/coder-amiao
 * 用户jwt token生成配置
 */
@Configuration
public class UserJwtConfig {


    @Bean
    public UserSign MyUserSign() {
        return new MyUserSign();
    }


    @Bean
    public UserJwtToken userJwtToken(UserSign MyUserSign) {
        UserJwtToken userJwtToken = new UserJwtToken();
        userJwtToken.setUserSign(MyUserSign);
        return userJwtToken;
    }
}

权限认证

基于JWT Web Token 也帮你封装了权限登录认证。 你只需要在属性文件配置开启即可。

yml
jwt:
  authorization:
    has-authorization: true
    includes-url: /user # 需要认证请求 多个用逗号隔开
    excludes-url: /login,/register/** # 配置无需认证的

全局帮你自动处理Token过期异常。和错误异常你只需要在 heard 中配置你自己的Token就行

json
{
  "success": false,
  "code": "401",
  "msg": "未授权 ",
  "requestId": "9a3ytEtOX0UuojSaA2LD",
  "timestamp": "2023-07-17 17:08:05",
  "data": null
}

如果需要自定义自己认证授权逻辑,实现LoginAuthorization接口即可 并且在UserJwtConfig配置类中注入对应LoginAuthorization bean

也可以通过继承默认实现LoginAuthorizationSubject 重写授权方法。建议此种。

如:

java
package cn.soboys.superaide.config;

import cn.soboys.restapispringbootstarter.Assert;
import cn.soboys.restapispringbootstarter.HttpStatus;
import cn.soboys.restapispringbootstarter.authorization.LoginAuthorization;
import cn.soboys.restapispringbootstarter.authorization.UserJwtToken;
import org.dromara.hutool.core.text.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/7/16 11:00
 * @webSite https://github.com/coder-amiao
 */
@Component
public class MyLoginAuthorization implements LoginAuthorization {
@Autowired
private UserJwtToken userJwtToken;

@Override
public Boolean authorization(HttpServletRequest request, HttpServletResponse response, Object handler) {
    String token = request.getHeader("Token");

    Assert.isFalse(StrUtil.isEmpty(token),HttpStatus.UNAUTHORIZED);
    String userId = userJwtToken.getUserId(token);  //验证token有效合法性。

    //其他数据库 或者业务操作
    return true;
}
}

在配置类中注入 bean

java
package cn.soboys.superaide.config;

import cn.soboys.restapispringbootstarter.authorization.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/7/15 09:49
 * @webSite https://github.com/coder-amiao
 * 用户jwt token生成配置
 */
@Configuration
public class UserJwtConfig {


    @Bean
    public UserSign MyUserSign() {
        return new MyUserSign();
    }

    @Bean
    @Primary
    public LoginAuthorization loginAuthorizationSubject() {
        return new MyLoginAuthorization();
    }


    @Bean
    public UserJwtToken userJwtToken(UserSign MyUserSign) {
        UserJwtToken userJwtToken = new UserJwtToken();
        userJwtToken.setUserSign(MyUserSign);
        return userJwtToken;
    }
}

三方权限认证框架

基于 JWT Web Token 也可以很轻松集成Shiro 或者是。Spring Security等其他第三权限框架

当然后续版本我会把权限认证独立出来一个完整轻量级权限框架项目。如: 通过注解@hasPerm,@hasRole,@hasAnyPerm,@hasAnyRoles 轻松实现相对复杂的权限认证。