JWT在身份验证与信息交换中的实践探索
JWT
JWT是指JSON Web Token,一种用于在网络上安全传输信息的开放标准(RFC 7519),定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。JWT由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature)。通常被用来在用户和服务器之间传递身份信息,以及在不同的系统之间安全地传递声明。JWT通常被用于身份验证和信息交换,特别是在前后端分离的应用中。
JWT工作示意图:
JWT由三部分组成,分别是头部(header)、载荷(payload)和签名(signature)。
JWT的三部分使用点号(.)连接起来,形成一个完整的JWT令牌。例如:xxxxx.yyyyy.zzzzz
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJaSEFOR1hVTiIsImJvZHkiOnsidXNlclJvbGUiOiJhZG1pbiIsInVzZXJpZCI6IjAwMSJ9LCJleHAiOjE2NjI5NTIxNjIsImlhdCI6MTY2Mjk1MTU1NywianRpIjoiZGZhN2MyZjUtNGNjMC00OWFhLWFiMDUtYzZhY2M4M2YxMDViIn0.xOleM21i7-EI0oOq83Xm-nQVOufajHCupY2QjkpwreQ
JWT通常用于身份验证和授权,因为它们可以包含用户的信息,并且可以被验证和信任。通常用于API认证,因为可以在多个系统之间安全地传递信息,而无需使用cookie或session。
JWT使用
com.auth0
java-jwt
4.4.0
@Slf4j
@RestController
public class TokenController {
@Autowired
private TokenUtil tokenUtil;
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password){
if(!"admin".equals(username) || !"123".equals(password)){
log.info("账号或者密码错误!");
}
// 模拟从数据库中获取的用户识别信息
String userId = "001";
String userRole = "admin";
Map dataMap = new HashMap();
dataMap.put("userId", userId);
dataMap.put("userRole", userRole);
// 将用户识别信息存储到token中
String token = tokenUtil.createToken(dataMap);
log.info("生成的token为:{}", token);
return token;
}
@PostMapping("/getUserInfo")
public String getUserInfo(@RequestParam String token){
if(ObjectUtils.isEmpty(token)){
log.info("token不能为空!");
return "token不能为空!";
}
log.info("收到的token为:{}", token);
Map dataMap = tokenUtil.parseToken(token);
String userRole = dataMap.get("userRole").toString();
if(!"admin".equals(userRole)){
log.info("非管理员角色,不允许访问!");
return "非管理员角色,不允许访问!";
}
String userId = dataMap.get("userId").toString();
return "允许登录,用户为:" + userId;
}
}
@Component
public class TokenUtil {
private static final String DEFAULT_SECRET = "666";
private static final String DEFAULT_DATA_KEY = "body";
private static final String DEFAULT_ISSUER = "REATHIN";
private static final Long DEFAULT_EXPIRE_TIME = 7*24*60*60L;
public String createToken(Map dataMap){
return createToken(dataMap, DEFAULT_SECRET);
}
public String createToken(Map dataMap, String secret){
// 指定使用的加密算法
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
.withClaim(DEFAULT_DATA_KEY, dataMap)
.withIssuer(DEFAULT_ISSUER)
.withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + DEFAULT_EXPIRE_TIME * 1000))
.withJWTId(UUID.randomUUID().toString())
.sign(algorithm);
}
public Map parseToken(String token){
return parseToken(token, DEFAULT_SECRET);
}
public Map parseToken(String token, String secret){
// 指定使用的加密算法
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier jwtVerifier = JWT.require(algorithm).build();
DecodedJWT decodedJWT = jwtVerifier.verify(token);
return decodedJWT.getClaim(DEFAULT_DATA_KEY).asMap();
}
}
JWT优缺点
优点:
缺点: