validate client id before granting access token with authentication using user credentials oauth2+doorkeeper+rails - ruby-on-rails

I have implemented oauth2 token request with username and password but I need to make client_id and secret validation before authentication. If there is no client_id or secret it should return an error message like "Invalid application". Is there any way to make client_id and secret a required field before authenticated with username and password.

you could use before_save at the top of your rb file and check to see if the params exist?
before_save :validate_stuff
def validate_stuff
unless params[:client_id].present? && params[:secret].present?
raise "Please enter all the info."
end
end
That will fire every time you try to save your object

Related

How to skip validation on regeneration of secure token

So I'm sending out password reset e-mails and I've hit a stump on how to solve this issue, so after the user has reset their password. I regenerate a new password reset token (I know this is bad, before I had it generate when I was sending out the password reset request, but that didn't work so I tried this.). Every time I regenerate the token it does not skip validations that I have set in the model.
As said before, I have tried switching it around, regenerating a new token before I send the e-mail and now after they have reset their password. I have also looked the documentation of has_secure_token and I don't see anywhere where I can skip validation when I regenerate a token.
This is my code for resetting the password in the User model.
def reset_password(password)
self.regenerate_reset_password_token
self.password = password
save(:validate => false)
end
I'm getting the error for validating my user's passwords, when regenerating the token, as said before not sure how to skip the validation when regenerating the token on line 2 of the code above.
Validation failed: Password can't be blank, Password is too short (minimum is 8 characters)
You can do
def generate_password_reset_token
self.reset_password_token = generate_token
self.reset_password_sent_at = Time.now
save!
end
def generate_token
SecureRandom.base58(5)
end

Devise token auth another user login

I am developing an application through Rails.
I need the ability to login to another user with admin account in devise token auth gem
When user log in, authHeaders are stored in the browser cookie.
Determine user by authHeaders value.
ex)
{ %22access-token%22:%22"access-token value"%22%2C
%22token-type%22:%22Bearer%22%2C
%22client%22:%22"client value"%22%2C
%22expiry%22:%"expiry value"%22%2C
%22uid%22:%22"uid value"%22}
in my controller
returns a new token value when admin clicks user id
def login_as
user = User.find(params[:user_id])
user_new_token_data = user.create_new_auth_token
## return new access-token, token-type, client, expiry, uid in browser cookies format same value
end
I want to change the return value to a browser cookie value and log in as another user, but I do not know how to put it in the cookie.
I would appreciate your help. Thank you

Devise finding user by reset token

I'm trying to make an api for resetting password, I made devise handle the part when the user press on forgot password and sending him an email with a token but I tried to change it in the other part I needed to look up user using that token when he reset his password but Devise reset_password_token of the user (in the DB) is not like the token sent in the email, I only receive token, password, password_confirmation to make that API work, So I need to find that user using token sent in the email(User.where(reset_password_token: TOKEN)), Is there a way to convert token in the email to the one I have in the DB.
You have to check the reset_password_by_token class method which contains the logic. But you can use it directly:
User.reset_password_by_token({
reset_password_token: token,
password: password,
password_confirmation: password_confirmation
})
Link to current master code here

Compare token plain text with token encrypted from Devise , Rails 5

I have app - Rails 5 with Devise. When user request new password, Devise generates token (plain text) which is send to the user email. After that Devise encrypt this token and save it to the database.
What I want is when user clicks to the link with token (plain text) for changing password, to compare this token from GET variable with this saved in the database (which is encrypted).
I see that Devise has method for this (validating URL token with encrypted in the database):
resource_class.confirm_by_token(params[:confirmation_token])
, but it is for registration (when user validates his email - confirmation link).
What I am trying is:
token_hash = BCrypt::Password.create(params[:reset_password_token])
user = User.find_by({reset_password_token: token_hash})
params[:reset_password_token] is the right value, but it returns nil.
The token is valid, because after that I can change the password.
If I do:
user = User.find_by_email('some email') # because I know which email is
token = BCrypt::Password.new(user.reset_password_token)
I am getting this error:
BCrypt::Errors::InvalidHash Exception: invalid hash
, but same code works, with user.encrypted_password.
I know how to get token from the URL, but how to compare it with this one saved in the database, which is encrypted ?
Devise gem encryption and decryption of password token
Devise gem has TokenGenerator class.Whenever you send reset_password_instructions
it generates friendly_token and corresponding encrypted token.It sends friendly_tokens in the email and stores encrypted token in Table.Now, whenever you submit that token It will encrypt your password token and compares it with one that is stored in your table.
Below example will elaborate more
Encryption
syntax:
Devise.token_generator.generate(class_name,column_name)
Example:
Devise.token_generator.generate(User,:reset_password_token)
["J9SkM77VENGQRZirVnoq", "2942dd29f8ddbd96ff59373a92bd3430e437f038efb81639532311a8d3a83467"]
So, *generate* method returns array with friendly_token at index 0 which will be sent to your email and a encrypted token at index 1 which will be stored in Table.
Decryption
syntax:
Devise.token_generator.digest(class_name,column_name, password_token)
Example
Devise.token_generator.digest(User,:reset_password_token, "J9SkM77VENGQRZirVnoq")
"2942dd29f8ddbd96ff59373a92bd3430e437f038efb81639532311a8d3a83467"

Secure Handling of Auth Tokens with Rails

I'm working on a new rails api project, and I'm trying to get to the best usability/security balance.
The user will establish a session by posting username/password to api/v1/sessions. For a valid user, it will create an authentication token, which is it's own activerecord model, associated by the polymorphic relationship authenticatable, giving me the flexibility to have multiple user models if I need to.
class AuthenticationToken < ActiveRecord::Base
before_create :digest_token
def self.from_authenticatable(authenticatable)
self.create(authenticatable: authenticatable, token: generate_token)
end
end
The undigested token (SecureRandom.hex) gets rendered back to the client via JSON to authenticate future requests. The token gets salted and digested for storage in the database using BCrypt and a configured work factor.
The client will provide the raw auth token and an identity (can be username or password) to load the user record. Authentication will be handled by authenticate_with_http_token
def authenticate_token
authenticate_with_http_token do |token, options|
user = User.identified_by(options["identity"])
user.authentication_tokens.any? do |auth_token|
#current_user = user if auth_token.secure_compare(token)
end
end
end
Auth tokens are compared via a constant time alogrithm lifted from devise.
If current user is not successfully set, I render 401 unauthorized.
I feel like this is reasonably secure, and the only thing I really want to do is add some more fields to the auth token to track where it was last used (user agent) to allow the user to revoke some of the auth tokens if they like.
Are there any major holes with this approach? Anything else I should consider?

Resources