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 */@Autowiredprivate UserRoleMapper userRoleMapper;// 动态实例化类对象private static UserLoginTokenUtil userLoginTokenUtil;/** * @PostConstruct * 1、首先这个注解是由Java提供的,它用来润饰一个非动态的void办法。它会在服务器加载Servlet的时候运行,并且只运行一次。 * 2、用于解决一般工具类中办法无奈被 static润饰,退出这个注解之后就能够在类初始化之前执行这个注解下的办法。 * 3、我这个就是工具类中无奈注入 mapper */@PostConstructpublic 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;}
}