Devise 3.1 Upgrade Invalid Token Error - ruby-on-rails

My app has been using devise (3.1.0, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 2.2.4), so the current version is 3.1.0. With this upgrade there is a new way Devise does token confirmation (blog).
When I click on the email link it leads to an invalid token error, so I'm trying to find out how to resolve this. Please let me know any pointers you have. Thank you.

With 3.1.0, Devise has changed the way it handles token authentication. Rather than storing an unencrypted token in the database, Devise now encrypts that token and sends the unencrypted token in the confirmation email. You will need to set config.secret_key in order to facilitate this encryption. More info on that here: Devise Secret Key was not set
Thus, if you have an old email, or an old token in the database, it is not likely to match what you expect. You can set
config.allow_insecure_token_lookup = true
in your Devise initializer file to remedy this problem, but this is supposed to be a short-term solution while you wait for users to click on the confirmation emails that you sent out before the switch.
Lastly, if you've changed the mail message to reference the token directly (e.g. #user.reset_password_token), you are using the encrypted version in the email and will need to change it to reference the #token variable defined by Devise instead. Here's an example email: https://github.com/plataformatec/devise/blob/2a8d0f9beeb31cd2287094c5dcf843d0bd069eb8/app/views/devise/mailer/reset_password_instructions.html.erb#L5

Related

Decoding a JWT token from a .cer file in Rails

I've been asked to solve a very specific problem. An outside company will authorize the user, and create a JWT token for that user. They will then send us a .cer file (.der and other file types are likely fine too). I then have to decode the JWT within the file.
Our Rails app's current authorization system uses Devise
I've tried finding ways to do this in the JWT gem. I've tried using the OpenSSL library to somehow read the file and turn it into an object that JWT.decode will read.
Let me know if more info is needed

HTTP basic authentication over Devise

I am trying to use HTTP Basic Authentication over Devise for my Rails app. I have done following settings ->
config.http_authenticatable = true in the devise initializer
And
:database_authenticatable strategy in my USER model.
When I try to access a web service
mysite.com/user/list.json?email=test#mysite.com&password=test123
The username password is not recognized. A credentials box pops up where on entering the credentials I am authenticated to use the data.
How can I provide the credentials in the URL and avoid the pop up prompt?
HTTP Basic Auth, is passed through HTTP Headers, not GET or POST params.
I found a way of doing this-->
http://username:password#test.com/users/list.json?

How to get password reset url in devise?

I am porting my data from old system to a new system written in ruby on rails. To get the older users registered I am planning to transfer their old data into new system but I can't transfer their old password so I'm planning to create a random password and then a password reset link and send them a custom email inviting them to my new system.
Devise provides this:
user.send_reset_password_instructions
But this sends a "forgot password" email to user. I just want to get the forgot password url somehow so that I can use that url in my own mail and send it at some later time. I've tried looking up but everywhere they talk about "send_reset_password_instructions" function. Any idea how I can do this?
The reset password url was formed by reset_password_token in User model.
So saving the reset_password_token is enough to recover reset password url later on.
reset_password_token = 'XYZ' # Example token
reset_password_url = Rails.application.routes.url_helpers.edit_user_password_path(reset_password_token: reset_password_token)
Due to security (an attacker could read the link from the database to bypass email verification), what Devise stores in user.reset_password_token is only a digest of the token that is sent into the password reset link.
Specifically, in the set_reset_password_token method, the encoded token is saved to the database, while the raw token is returned and then sent in the password reset email.
What you can do is to reset the token yourself and save the raw token somewhere to be used later:
raw = user.send(:set_reset_password_token)
It's also worth noting that you can customize the devise mailer and provide your own templates. However, in this case, it would also affect the legitimate password reset emails.

Devise Warden Authentication Fails First Time, Succeeds After

I am using Devise to authenticate users for my rails app using database authentication (for username and password) and token authentication for an API that I built with Grape. Devise is generating an authentication token as expected. However, it seems that authentication always fails after the first request and works subsequent times. I am calling authenticate! before my API calls in Grape, which is defined as follows:
def authenticate!
error!({"error" => "Unauth 401"}, 401) unless env['warden'].authenticate
end
This is very odd behaviour. If I try to login with the browser first, then via a curl call to the API, it works. It seems that the first request will just always fail after a server restart.
Is that the expected behaviour? If so, why is that and how do I avoid it? Do authentication key logins always need a regular login via the browser first?
P.S: I did read Devise authentication fails on first attempt, succeeds afterwards, but it does not seem to answer the question.

Is it ok to use BCrypt's generate_salt method to create a token for password resetting in ruby on rails?

I'm creating a password_reset feature in rails the same way I did it when I used codeigniter.
For a user to reset their password, they type in their email address and click a button. The token is generated and stored in the database, and an email is sent to their email address with a URL containing that token.
When user clicks the link in the email, a method is called that checks that the token in their email matches the token stored in the db.
Now my question is: is it ok to use BCrypt's generate_salt method to generate this token, or is there some other way I should be doing this?
SecureRandom.hex is more suitable in that case.
since the modern encrption mechanism like shai doesnt allow decryption of the currrent passwords it is mandatory one to generate a new password. bcrypt should be fine doing this

Resources