Time-based expiration mechanism for tokens
Closed this issue ยท 7 comments
Hello,
Really love the work you did with this gem!
Currently as much as I see, tokens can be used forever, there is no support for generating tokens that last for a certain amount of time (e.g. 2 weeks).
Do you plan on supporting something like this, and what's your take on this?
@DamirSvrtan thanks for the great discussion (and presentation) about that at Southeast Ruby.
As I said, the project from which I extracted Tiddle didn't have a need for tokens that expire after a certain amount of time. However, it sounds like a very reasonable use case so I'm willing to cover it.
The most "straightforward" option that I can see is manually adding a Rake task that does something like:
AuthenticationToken.where("created_at < ?", 2.weeks.ago).delete_all
This has the disadvantage of being imprecise. If the Rake runs every hour then we have a chance of allowing authentication with a token that should have already been expired.
Because of that, we may consider a better alternative. For me two most important requirements are:
- backwards compatible
- does not introduce a configuration option to Tiddle
What I came up with is:
- add
expires_at
field to the table that stores authentication tokens - add
expires_at
keyword argument defaulting to nil toTiddle.create_and_return_token
- in the strategy compare
expires_at
with the current time and refuse to authenticate user when the token is too old.
This allows to precisely specify the expiration time, and, for example, use different values depending on user role (admin, non-admin).
Does this sound reasonable?
I'd like to chip in, as I'm on a lookout for token based auth for app I'm working on and your gem has attracted my attention.
Time based expiration/revoke mechanism is a must in my opinion. I'm actually surprised that it wasn't included by default. I want to implement an api handling self expiring tokens, but it would require multiple tokens in order for the api to be accessed by multiple devices, without cutting them off all at once when token gets revoked.
What you propose above seems like the most feasible option. I actually wanted to fork this and try to add this part myself, when I noticed this issue. I'm eager to see this in action.
Also, I have another idea. Facebook, for example, expires/revokes the tokens after a period of inactivity. So maybe:
- instead of
expires_at
maybe useexpires_in
integer field - keyword argument would also be names like
expires_in
where you could pass a duration argument like3.months
- strategy would take
last_used_at
withexpires_in
added, which, when compared with current time would revoke the token or not
What do you think? It would be more flexible, without necessarily forcing users to relogin if they use the api/token on regular basis.
@riggy thanks for contributing to the discussion!
I'm actually surprised that it wasn't included by default.
As I said earlier, this wasn't the focus of the project I extracted this gem from.
I actually wanted to fork this and try to add this part myself
Please do and contribute back as a PR!
I'm fine with the approach that you presented (expiring the token after a period of inactivity).
@adamniedzielski I actually went other way with implementing devise_token_auth
- it was more fitting into our policy as it's compliant with RFC 6750 Bearer Token. However I made the adjustments prior to that. I'm gonna open a PR in a bit. Commits are messy as I committed a bunch of rubocop based fixes reverting them later to make PR more strict to the topic.
Implemented by #37