API signin to generate token using devise in rails 4

大憨熊 提交于 2020-08-05 10:57:24

问题


I am implementing api via rails.

I want to implement following feature but unable to figure out how?

I tried this sample app

I have user model with email, password and access_token

class UsersController < ApplicationController

   def signin


        c_user = User.find_by_email(params[:email])
        pass = params[:password]
        if c_user.password == pass

          render json: c_user.access_token
        end  

   end


   private  
    def users_params    
        params.require(:user).permit(:email, :password) 
    end

end

If user request via api for http://localhost:3000/signin?email=t1@t.com&password=password

then it will check email and password and return access_token that user can use for future request.

I want to implement same with devise or any other gem please help me to understand it. Thanks in advance


回答1:


This is how I emplement such mechanism in my apps:

  • Generate an access_token whenever a user is created.
  • Respond with that access_token whenever the user signs in.
  • Require an access_token authentication for every request needed.

user.rb

class User < ActiveRecord::Base
  # Use this before callback to set up User access_token.
  before_save :ensure_authentication_token

  # If the user has no access_token, generate one.
  def ensure_authentication_token
    if access_token.blank?
      self.access_token = generate_access_token
    end
  end

  private

    def generate_access_token
      loop do
        token = Devise.friendly_token
        break token unless User.where(access_token: token).first
      end
    end
end

application_controller.rb

class ApplicationController < ActionController::Base

  private

  # To make authentication mechanism more safe,
  # require an access_token and a user_email.
  def authenticate_user_from_token!
    user_email = params[:user_email].presence
    user       = user_email && User.find_by_email(user_email)

    # Use Devise.secure_compare to compare the access_token
    # in the database with the access_token given in the params.
    if user && Devise.secure_compare(user.access_token, params[:access_token])

      # Passing store false, will not store the user in the session,
      # so an access_token is needed for every request.
      # If you want the access_token to work as a sign in token,
      # you can simply remove store: false.
      sign_in user, store: false
    end
  end
end

Then you can use this before_filter in any controller you want to protect with access_token authentication:

before_filter :authenticate_user_from_token!

You also needs to override Devise sessions controller, so it responds with a JSON holding the access_token.

users/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController

  # Disable CSRF protection
  skip_before_action :verify_authenticity_token

  # Be sure to enable JSON.
  respond_to :html, :json

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_flashing_format?
    sign_in(resource_name, resource)
    yield resource if block_given?

    respond_with resource, location: after_sign_in_path_for(resource) do |format|
      format.json { render json: {user_email: resource.email, access_token: resource.access_token} }
    end
  end

end

And make sure to specify it in your routes:

routes.rb

devise_for :users, controllers: { sessions: 'users/sessions' }



回答2:


I think the reason you can't do that is because there is no password field as you were expected. There is only encrypted_password in the table.

And you must not save any user's password explicitly in a field like password for security reasons.

The way you can make your api work is by using valid_password? method provided by devise to authenticate the user.

if c_user.valid_password?(params[:password])
  ... ...
end


来源:https://stackoverflow.com/questions/29853474/api-signin-to-generate-token-using-devise-in-rails-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!