I’ve created a Laravel application which requests my users access to an external application using oAuth (authorization code). All good, I’m able to connect the external application to my users’ accounts. However, the external API gives me an access and refresh token. The access token obviously expires, the refresh token doesn’t.
Once the user has granted me access, I need to store these tokens somewhere. Especially the refresh token. Once the access token expires, I need to refresh the access token. My "problem" is, I’m not quite sure where to store these tokens. I have thought of a few options:
- Storing encrypted tokens in the database, linked to the user
- Store them in cache
- Store them in Redis database
- …
There are many options, but I’m looking for the safest one. Storing the encrypted tokens in the database isn’t my favorite choice, but the most persistent one. Cache can be cleared, deliberately or not. When the cache is cleared, I need the user to grant me access to their account again.
What’s the best way of storing these credentials?
2
Answers
Security
No matter where you store it, always do it in an encrypted format. This way even if leaked they cannot be reused, unless the encryption key is also leaked.
Refresh Token Persistence
You can do it with sessions, JWT tokens or directly into a database. Let’s see the options…
Laravel Sessions
If you are using user sessions in your Laravel application you can store it encrypted in the session for each user.
Laravel Sessions
Laravel also supports to store the session in encrypted cookies.
JWT Tokens
If you are using JWT tokens then your are probably using a JWS token, then if so store it encrypted in a JWS claim or even better, use JWE tokens.
The claim in a JWT token is a key/value pair in the payload of the JWT token. The JWT Token is composed by
header.payload.signature
. Payload example:JWS
JWE
You can learn more about JWT at https://jwt.io/introduction.
Databases
Use the database more convenient for you, aka the one already available in your application. Don’t introduce Redis just to store the refresh token, but if you already have Redis in use, then it can be an alternative, but I would just store it encrypted in the database you already store the user info. After all refreshing a token is not an operation you do in every request, therefore performance may not be so critical here.
Memory and encrypted db are your best bet. Memory would not be enough as you will lose it in case of a memory flush of any kind. So you are left with encrypted DB