如何使用 Java 创建身份验证令牌

2022-09-01 05:06:57

在我的Java EE6,REST服务上,我想使用认证令牌从移动设备登录,用户将发送他们的用户名,密码,服务器将发回一个令牌,该令牌将用于授权用户在给定时间内的进一步请求。

我可以像这样自己创建一个令牌吗?(我想我不需要加密它,因为我将使用HTTPS。

String token = UUID.randomUUID().toString().toUpperCase() 
            + "|" + "userid" + "|"
            + cal.getTimeInMillis();

或者有更标准的方法可以创建这些令牌?也许它存在于其中一个API中?


答案 1

对于Java 8及更高版本,最快,最简单的解决方案是:

private static final SecureRandom secureRandom = new SecureRandom(); //threadsafe
private static final Base64.Encoder base64Encoder = Base64.getUrlEncoder(); //threadsafe

public static String generateNewToken() {
    byte[] randomBytes = new byte[24];
    secureRandom.nextBytes(randomBytes);
    return base64Encoder.encodeToString(randomBytes);
}

输出示例:

wrYl_zl_8dLXaZul7GcfpqmDqr7jEnli
7or_zct_ETxJnOa4ddaEzftNXbuvNSB-
CkZss7TdsTVHRHfqBMq_HqQUxBGCTgWj
8loHzi27gJTO1xTqTd9SkJGYP8rYlNQn

上面的代码将生成具有32个字符的base64编码的随机字符串。在 Base64 中,每个字符编码 6 位数据。因此,对于上面示例中的24个字节,您将获得32个字符。您可以通过更改随机字节数来更改输出字符串的长度。此解决方案比(仅使用 16 个随机字节)更安全,并且生成可以安全地在 HTTP URL 中使用的字符串。UUID


答案 2

要在Java中创建难以猜测的令牌,请使用java.security.SecureRandom

例如:

SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String token = bytes.toString();

与其在令牌中包含用户名,不如将 user:token 映射缓存在内存或数据库中。