Java JWT实现跨域身份验证方法详解
什么是JWT
JWT(JSON Web Tokens)是一种用于身份验证的安全传输方式。JWT 通常被用于在客户端和服务器之间传递身份识别信息,以便于进行身份验证和授权。
JWT的组成
JWT 由三部分组成,分别是:
- Header,头部信息,包含JWT的类型以及算法。
- Payload,负载信息,包含需要传递的数据。比如:用户id、用户名等数据。
- Signature,签名信息,用于验证该JWT是否合法,由Header和Payload结合密钥生成。
Java JWT实现过程
Java 开发者可以使用 Java JWT库 来处理JWT消息。自定义一个 JWT 工具类,利用它提供的 API 实现 JWT 的签名和验证。
JWT签名
使用如下方法生成JWT:
public static String generateToken() {
//构建header
Map<String, Object> headerClaims = new HashMap<>();
headerClaims.put("alg", "HS256");
headerClaims.put("typ", "JWT");
//构建payload
Map<String, Object> payloadClaims = new HashMap<>();
payloadClaims.put("sub", "1234567890"); // 该JWT所面向的用户ID
payloadClaims.put("name", "John Doe"); // 用户名,自定义字段
payloadClaims.put("iat", new Date().getTime() / 1000); // JWT的签发时间
payloadClaims.put("exp", new Date().getTime() / 1000 + 60 * 60); //JWT的过期时间,一小时后过期
//签名密钥
String secret = "my-secret";
//使用builder生成jwt字符串
String jwt = "";
try {
jwt = JWT.create()
.withHeader(headerClaims)
.withIssuer("auth0")
.withSubject("1234567890")
.withExpiresAt(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
.withClaim("name", "John Doe")
.withClaim("iat", new Date().getTime() / 1000)
.withClaim("exp", new Date().getTime() / 1000 + 60 * 60)
.sign(Algorithm.HMAC256(secret));
return jwt;
} catch (Exception exception) {
exception.printStackTrace();
}
return jwt;
}
上述方法中,先构建了JWT的header和payload部分,应该根据业务需求自定义所需数据。然后在代码中指定了使用HMAC256算法来对JWT进行签名,签名所需的秘钥为“my-secret”,最后生成JWT字符串并返回。
JWT验证
使用如下方法验证 JWT:
public static boolean verifyToken(String token) {
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("my-secret")).build(); //构建JWT验证器
DecodedJWT jwt = verifier.verify(token); //解码JWT
return true;
} catch (Exception exception) {
exception.printStackTrace();
}
return false;
}
上述方法中,首先使用JWTVerifier构建一个JWT验证器,指定签名算法为HMAC256,签名秘钥为“my-secret”,然后使用该验证器对传入的JWT进行验证。如果验证通过,返回 true,否则返回 false。
基于JWT实现跨域身份验证方法示例
示例1:使用Java JWT在微服务中实现跨域身份验证
假设有两个微服务 A 和 B,其中 A 服务中需要向 B 服务发送一个需要身份验证的请求,此时可以将JWT作为验证信息在 A 服务中生成并携带到 B 服务。示例代码如下:
//A服务中生成JWT并携带到B服务
String jwt = JwtUtil.generateToken();
URL url = new URL("http://localhost:8080/b");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//将JWT放入请求头中
conn.setRequestProperty("Authorization", "Bearer " + jwt);
InputStream input = conn.getInputStream();
在 B 服务接收到 A 服务的请求后,可以从请求头中获取到 JWT,并对其进行校验,示例代码如下:
//B服务中校验JWT
String jwt = request.getHeader("Authorization");
if (jwt != null && jwt.startsWith("Bearer ")) {
jwt = jwt.substring("Bearer ".length());
if (JwtUtil.verifyToken(jwt)) { //校验JWT
// JWT校验成功,执行对应的业务逻辑
}
}
示例2:使用Java JWT实现跨域单点登录
假设我们已经在服务器端设置了一个登录页面,并且在登录成功后生成了一个JWT。此时将该JWT放入响应的Header中,返回给客户端。示例代码如下:
//若登录成功,生成JWT并设置响应的Header中
String jwt = JwtUtil.generateToken();
response.setHeader("Authorization", "Bearer " + jwt);
此时客户端可以获取到该JWT,将其存储在 localStorage 或 sessionStorage 中,以便在其他页面中获取。假设现在客户端需要访问另一个页面 page2,该页面需要进行身份验证才能访问。此时,可以从 localStorage 或 sessionStorage 中获取该JWT,并将其放入请求头中,示例代码如下:
//在客户端页面中向服务器发送请求,并携带JWT
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/page2');
var jwt = localStorage.getItem("jwt");
xhr.setRequestHeader('Authorization', 'Bearer ' + jwt);
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
}
};
xhr.send();
在服务器端根据请求头中携带的JWT进行校验,示例代码如下:
//在服务器端根据JWT进行校验
String jwt = request.getHeader("Authorization");
if (jwt != null && jwt.startsWith("Bearer ")) {
jwt = jwt.substring("Bearer ".length());
if (JwtUtil.verifyToken(jwt)) { //校验JWT
// JWT校验成功,执行对应的业务逻辑
}
}
以上就是使用Java JWT实现跨域身份验证的基础方法和应用场景的示例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java JWT实现跨域身份验证方法详解 - Python技术站