Currently I'm starting to pulling my hairs out on this. I've done some researching the past days and it seems that I do not get quite the point how to achieve the following:
I'm currently building a an API in Rails with a mobile application as the client. The mobile application can be either iOS or Android. Now I'm struggling with the authentication. After the client has logged in on the device, I issue a JWT with a short expiration. So if the token expires, the client needs to re-login, which is unacceptable UX in my case. Anyway, I feel that I need to have some kind of expiration to prevent the token from being used forever if it has been stolen.
Now I wonder how to integrate the refresh tokens. How do I ensure that the user can get a new access token only with a valid refresh token which has been issued to this exact device? Or am I overcomplicating things and assigning one refresh token which can be used on alle devices will do the trick?
Update: I've looked into the doorkeeper gem, which supports the password grant flow. But the way doorkeeper handles the tokens is, that it stores every generated access token in a database with a corresponding refresh token. When the token has been revoked or refreshed, the old access token gets invalidated - this will grow to a huge database table over time.
Additionally I prefer using JWT as the token, so I don't have to store anything but the refresh token in the database. Would the following process be secure?
- User requests access token with username / password and - let's say a devices name.
- Server issues JWT and creates a refresh token for the current device.
- The server stores the refresh token.
- When the access token expires, the user requests a new one by using it's refresh token.
- The server validates the refresh token and issues a new access token. Additionally, the refresh token gets replaced with a new one.
My questions on this: The user could be logged in in multiple devices, how to differentiate between them?