Explicitly invalidating signed global id after it's been used once

I’ve been following the Rails for Beginners tutorial on GoRails. On part 22 we are using Global IDs to create a token to use for password reset when a user has forgotten their password.

However I’ve figured out that we can still use the same token until it’s expired as many times as we want, to reset the password again and again.

I would like the token to be invalidated once it’s been used to reset the password once. I’ve checked the Github page but I couldn’t find anything about invalidating a token explicitly before it’s expiration time.

Can we invalidate a token explicitly before it’s expiration time?

I believe that the way Devise deals with this is to zero out the token (which is saved in the User model) once the password changes. You might look into adding this to your password-change flow in your authentication system.

Walter

So first I need to add an attribute to my User model called token. Once a token is created using globalid I need to assign it to user.token as well and then set it to nil maybe once the password is changed.

Here I think I would have to compare whether the token is actually matching user.token and then do the rest.

Thanks! I was just curious about it.

Recently I’ve been thinking about how to implement this behavior in a secure way. I took a stab at it in https://github.com/rails/rails/pull/43620. As you can see in that PR, I went with signed_id instead of Global ID, because Global ID shouldn’t necessarily have knowledge of the Active Record attributes interface. I believe it should still work for your use case, though, assuming you are using bcrypt.