Rails API : Best way to implement authentication?

前端 未结 4 1910
清酒与你
清酒与你 2020-12-12 17:35

I\'m writing a Rails 4 app that will expose an API for a mobile app that\'s yet to be developed. Users will authenticate using an e-mail and password from the mobile app.

4条回答
  •  抹茶落季
    2020-12-12 18:34

    Another option is to include the module below in your devise MODEL and add the auth_token to you table.

    app/models/concerns/token_authenticable.rb

    module TokenAuthenticatable
      extend ActiveSupport::Concern
    
      included do
        before_save :ensure_auth_token
      end
    
      module ClassMethods
        def find_by_token(token)
          find_by(auth_token: token)
        end
      end
    
      def ensure_auth_token
        self.auth_token = generate_auth_token if auth_token.blank?
      end
    
      private
    
      def generate_auth_token
        loop do
          token = Devise.friendly_token
          break token unless self.class.exists?(auth_token: token)
        end
      end
    end
    

    app/controllers/api/v1/login_controller.rb

    ...
     def login_user(params)
        if params[:authentication]
          @user = User.find_by(auth_token: params[:authentication])
          if @user.nil?
            render json: err('login user by token failed', ERR_USER_NOT_FOUND), status: :not_found
            event('login_user_by_auth_failed', 'token', params[:authentication])
            return
          else
            render status: :ok, json: @user
            return
          end
        else
          user = user.find_by(email: params[:email])
          if user.nil?
            event('login_user_failed_not_found', 'user_email', params[:email])
            render json: err("login user not found #{params[:email]}", ERR_USER_NOT_FOUND), status: :not_found
            return
          end
          if user.access_locked?
            event('login_user_blocked', 'user_id', user.id)
            render json: err("login user account is locked : #{user.id}", ERR_USER_LOCKED), status: :unauthorized
            return
          end
          unless user.try(:valid_password?, params[:password])
            event("login_user_password_does_not_match #{user.id}", 'user_id',  user.id)
            render json: err('login user password does not match', ERR_PASSWORD_NOT_MATCH), status: :unauthorized
            return
          end
          event('login_user_succeeded', 'user_id', user.id)
          @user= user
          if @user.save
            response.headers['authentication'] = @user.auth_token
            render status: :ok, json: @user
            return
          else
            render json: @user.errors, status: :unprocessable_entity
            return
          end
        end
      end
    ...
    

    Edit: Corrected code-breaking typo

提交回复
热议问题