共计 3214 个字符,预计需要花费 9 分钟才能阅读完成。
import cn.hutool.core.util.ObjectUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.jwt.demo.config.UserLoginPermission;
import com.jwt.demo.db.bean.UserRole;
import com.jwt.demo.db.mapper.UserRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
- token 工具类
- @author chenlirun
- @date 2021/7/8 17:27
*/
@Component
public class UserLoginTokenUtil {
/** | |
* 查问用户拜访权限 | |
* @author chenlirun | |
* @date 2021/7/18 17:36 | |
*/ | |
@Autowired | |
private UserRoleMapper userRoleMapper; | |
// 动态实例化类对象 | |
private static UserLoginTokenUtil userLoginTokenUtil; | |
/** | |
* @PostConstruct | |
* 1、首先这个注解是由 Java 提供的,它用来润饰一个非动态的 void 办法。它会在服务器加载 Servlet 的时候运行,并且只运行一次。* 2、用于解决一般工具类中办法无奈被 static 润饰,退出这个注解之后就能够在类初始化之前执行这个注解下的办法。* 3、我这个就是工具类中无奈注入 mapper | |
*/ | |
@PostConstruct | |
public void init(){userLoginTokenUtil=this;} | |
// 设置 token 过期工夫为 30 分钟 | |
public static final long EXPIRE_TIME=30*60*1000; | |
/** | |
* 生成 token 签名,30 分钟后过期 | |
* | |
* @author chenlirun | |
* @date 2021/7/8 17:52 | |
*/ | |
public static String sign(Long id){Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); | |
// 设置 jwt 令牌,Algorithm.HMAC256() 加密令牌 | |
Algorithm algorithm = Algorithm.HMAC256(TokenLoginInfo.secret); | |
return JWT.create().withClaim("id",id) // 设置属性,能够是以后登录的用户信息,给 Payload | |
.withExpiresAt(date) // 设置过期工夫 | |
.withIssuedAt(new Date()) // 设置以后创立工夫 | |
.sign(algorithm); // 签发一个新的 jwt 令牌 | |
} | |
/** | |
* 校验 token | |
* @author chenlirun | |
* @date 2021/7/8 17:56 | |
*/ | |
public static boolean verify(String token,Long id,String secret){ | |
try {Algorithm algorithm = Algorithm.HMAC256(secret); | |
/** | |
* JWT.require(): 验证签名的算法 | |
* .build(): [PerfectMoney 下载](https://www.gendan5.com/wallet/PerfectMoney.html) 应用曾经提供的配置创立一个新的可重用的 JWTVerifier 实例。* 返回: 一个新的 jwtverification 实例。*/ | |
JWTVerifier verifier = JWT.require(algorithm).withClaim("id", id).build(); | |
verifier.verify(token); | |
return true; | |
}catch (Exception e){return false;} | |
} | |
/** | |
* 解析 token,id | |
* @author chenlirun | |
* @date 2021/7/9 11:20 | |
*/ | |
public static Long getTokenById(HttpServletRequest request){String token = request.getHeader("token"); | |
/** | |
* 解码给定的 Json Web 令牌。* 留神,这个办法并不验证令牌的签名! 只有在您信赖令牌或您曾经验证了它时才应用它。* 返回: 解码后的 jwt。抛出:JWTDecodeException | |
* - 如果令牌的任何局部蕴含一个有效的 jwt 或每个 jwt 局部的 JSON 格局。*/ | |
DecodedJWT decode = JWT.decode(token); | |
return decode.getClaim("id").asLong();} | |
/** | |
* 认证 token | |
* @author chenlirun | |
* @date 2021/7/16 14:56 | |
*/ | |
public static boolean validToken(HttpServletRequest request, UserLoginPermission tag){String token = request.getHeader("token"); | |
if(token==null){throw new BaseException(BaseCodeResult.ERROR,"以后未登录"); | |
} | |
Long userId = UserLoginTokenUtil.getTokenById(request); | |
// 验证 token 签名 | |
System.out.println(TokenLoginInfo.secret); | |
boolean verifySuccess = UserLoginTokenUtil.verify(token, userId, TokenLoginInfo.secret); | |
if(!verifySuccess){throw new BaseException(BaseCodeResult.ERROR,"token 签名不正确"); | |
} | |
// 验证拜访权限 | |
UserRole userRole = userLoginTokenUtil.userRoleMapper.selectByUserId(userId); | |
Byte roleId = userRole.getRoleId(); | |
if (ObjectUtil.isEmpty(userRole)){throw new BaseException(BaseCodeResult.ERROR,"该用户无可用权限"); | |
} | |
/** | |
* String.indexOf() | |
* 返回此字符串中指定子字符串的第一个匹配项的索引。* 返回的索引是 k 中最小的值: 这. 开始与(斯特,k)如果 kexists 没有这个值,则返回 -1。* str - 要搜寻的子字符串。* 返回: 指定子字符串第一个匹配项的索引,如果没有匹配项则返回 -1。*/ | |
int i = tag.role().indexOf(String.valueOf(roleId)); | |
if(i == -1){throw new BaseException(BaseCodeResult.ERROR,"无拜访权限"); | |
} | |
return true; | |
} |
}
正文完