一种加密算法,Java用jave-jwt实现
pom里面加
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.2</version>
</dependency>
测试(包括编码与解码)
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.util.Date;
@Slf4j
public class JWTtest {
@Test
public void test01(){
//将用户的账号和姓名信息封装到一个token(令牌)中
String u_id="wang";
String u_name="大王";
//创建一个加密算法对象
String secret ="123456";
Algorithm algorithm= Algorithm.HMAC256(secret);
//创建一个令牌的构建者(建造者模式)
JWTCreator.Builder builder= JWT.create();
//为构建者设置令牌需要封装的信息(claim,包括名和值两部分)
//最后通过sign方法传入加密算法签名生产要给令牌
String token= builder
.withClaim("UserID",u_id)
.withClaim("UserName",u_name)
.withExpiresAt(new Date(System.currentTimeMillis()+10000))
.sign(algorithm);
log.info(token);
}
@Test
public void test02(){
String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VyTmFtZSI6IuWkp-eOiyIsIlVzZXJJRCI6IndhbmciLCJleHAiOjE2NTI1Nzg2MDN9.DWcCGGKCVL1SXGYeuPNItzxxZyuUQ1c07mCJlNhBwSs";
//解析令牌
DecodedJWT decodedJWT=JWT.decode(token);//对令牌进行解码获得经过解码的令牌
String UserID=decodedJWT.getClaim("UserID").asString();
String UserName=decodedJWT.getClaim("UserName").asString();
log.debug("userid:{},username:{}",UserID,UserName);
}
}
验证令牌
@Test
public void test03(){
//通过密匙,创建一个加密算法对象
String secret ="123456";
Algorithm algorithm= Algorithm.HMAC256(secret);如果密钥不对会抛出SignatureVerificationException
//获取验证器的建造者
//Verification verification=JWT.require(algorithm); //如果令牌过期会抛出TokenExpiredException
Verification verification=JWT.require(algorithm).withClaim("UserName","王");//如果没能匹配会抛出InvalidClaimException
String token="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VyTmFtZSI6IuWkp-eOiyIsIlVzZXJJRCI6IndhbmciLCJleHAiOjE2NTI1Nzg2MDN9.DWcCGGKCVL1SXGYeuPNItzxxZyuUQ1c07mCJlNhBwSs";
JWTVerifier verifier=verification.build();
verifier.verify(token);//验证通过返回解码后的令牌,否则抛出异常
}
登录令牌的使用
1.在网关配置中取消如下配置或改为false
allowCredentials: true #允许客户端发送凭据(含sessionid 的cookie),使用令牌机制此配置应去掉
2.在spring安全核心配置中,配置不使用session追踪用户
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
3.在spring security,修改登录成功后的处理器,在这里生成令牌,并向客户端发送
private void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException {
CurrentUser currentUser=(CurrentUser) authentication.getPrincipal();
TokenUser tokenUser=new TokenUser(currentUser.getUserId(),currentUser.getUserName());
String token= TokenUtils.sign(tokenUser,currentUser.getPassword());
print(response,Result.OK("登陆成功",token));
}