I am in the middle of implementing authentication and authorization service for my web application, already have the login section(Creating access and refresh tokens). But I'm curious what are the best practices for maintaining the user access. What I have so far:
public function authenticate(string $login, string $password): array
{
$subject = $this->subjectRepository->findByLogin($login);
// Used for blacklisting tokens
$sessionUuid = Uuid::uuid4();
if (!$subject) {
throw new UserNotFoundException();
}
// Skipped checking hash for simplicity as this is a sandbox
if ($subject->getPassword() !== $password) {
throw new InvalidCredentialsException();
}
// User is valid at this point
// Sign access token
$accessToken = $this->jwtSigner->sign([
'session_id' => $sessionUuid,
'sub' => $subject->getUsername(),
'exp' => (new \DateTime())->modify('+15minutes')->getTimestamp(),
'iat' => (new \DateTime())->getTimestamp(),
]);
// Sign refresh token
$refreshToken = $this->jwtSigner->sign([
'session_id' => $sessionUuid,
'sub' => $subject->getUsername(),
'exp' => (new \DateTime())->modify('+31days')->getTimestamp(),
'iat' => (new \DateTime())->getTimestamp(),
]);
return [
JsonWebToken::ACCESS_TOKEN => $accessToken,
JsonWebToken::REFRESH_TOKEN => $refreshToken,
];
}
Brief summary find the user by username, created new UUID for the "session" for finding the refresh token in the database(blacklisting + purge user sessions functionality). Check the credentials and sign 2 tokens, 15 minutes long valid access token and 31 days refresh token(pleas comment on the duration)
I won't go through validating if the access token is valid or not since it's dead simple. I wonder how should I take care of refreshing the access token.
Should I find the refresh token by the corresponding session_id, validate it, create new refresh token(or not?) and pass the new access token to the response body as an additional field access_token per say?
Do you find any serious vulnerabilities in this approach?
Did I forget about something important in the process?
Thanks in advance for your help and insights.