I am trying to create session tokens for my REST API. Each time the user logs in, I am creating a new token by
UUID token = UUID.randomUUID();
user.setSessionId(token.toString());
Sessions.INSTANCE.sessions.put(user.getName(), user.getSessionId());
However, I am not sure how to protect against duplicate sessionTokens.
For example: Can there be a scenario when user1 signs in and gets a token 87955dc9-d2ca-4f79-b7c8-b0223a32532a
and user2 signs in and also gets a token 87955dc9-d2ca-4f79-b7c8-b0223a32532a
?
Is there a better way of doing this?
If you get a UUID collision, go play the lottery next.
From Wikipedia:
Randomly generated UUIDs have 122 random bits. Out of a total of 128 bits, four bits are used for the version ('Randomly generated UUID'), and two bits for the variant ('Leach-Salz').
With random UUIDs, the chance of two having the same value can be calculated using probability theory (Birthday paradox). Using the approximation
p(n)\approx 1-e^{-\tfrac{n^2}{{2x}}}
these are the probabilities of an accidental clash after calculating n UUIDs, with x=2122:
n probability 68,719,476,736 = 236 0.0000000000000004 (4 × 10−16) 2,199,023,255,552 = 241 0.0000000000004 (4 × 10−13) 70,368,744,177,664 = 246 0.0000000004 (4 × 10−10)
To put these numbers into perspective, the annual risk of someone being hit by a meteorite is estimated to be one chance in 17 billion, which means the probability is about 0.00000000006 (6 × 10−11), equivalent to the odds of creating a few tens of trillions of > UUIDs in a year and having one duplicate. In other words, only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%. The probability of one duplicate would be about 50% if every person on earth owns 600 million UUIDs.