I wanted to build API for my existing application. The special authentication token was generated and added to my database. The problem is that when it comes to comparing between token sent by user application with the one defined in the database, I get such error:
NameError (uninitialized constant ActiveSupport::SecurityUtils): app/controllers/api/v1/base_controller.rb:64:in `authenticate_user!'
Rendered /home/snow/.rvm/gems/ruby-2.0.0-p643/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (25.4ms)
Rendered /home/snow/.rvm/gems/ruby-2.0.0-p643/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (0.8ms)
Rendered /home/snow/.rvm/gems/ruby-2.0.0-p643/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (29.9ms)
Rendered /home/snow/.rvm/gems/ruby-2.0.0-p643/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (74.0ms)
Or you can see the response from postman:
Searching the Web for answer, it appeared that it may be caused by the incompatibility of Rails version and secure_compare
method. (My application is built on Rails 4.0.2 while it is needed to use Rails 4.2.0.) Is rails upgrading the only solution for my problem, or is there any other way to securely compare tokens without using ActiveSupport::SecurityUtils
?
Authentication code is here:
def authenticate_user!
token, options = ActionController::HttpAuthentication::Token.token_and_options(request)
user_phone_number = options.blank?? nil : options[:phone_number]
user = user_phone_number && User.find_by(phone_number: user_phone_number)
if user && ActiveSupport::SecurityUtils.secure_compare(user.authentication_token, token)
@current_user = user
else
return unauthenticated!
end
end