如何使用Devise辅助方法

时间:2017-04-29 18:50:46

标签: ruby-on-rails ruby devise warden ruby-on-rails-5.1

我正在尝试为我的客户端构建一个Rails服务器,同时实现Devise控制器,并且面临很多问题。

  1. 使用Warden.authenticate(resource_name)!进行日志记录时,我会收到“401未授权”,但我可以通过设备的sign_in方法正确注册。

  2. 在通过auth_token登录后尝试使用辅助方法时,我得到所有辅助方法的nil和默认值。

  3. 版本:

    • Rails v5.0.2
    • ruby​​ v2.2.3
    • Devise v4.2.0

    应用程序控制器:

    class ApplicationController < ActionController::Base
    
      protect_from_forgery with: :exception
    
      skip_before_filter :verify_authenticity_token,
                         :if => Proc.new { |c| c.request.format ==  'application/json' }
    
    
    
     before_filter :authenticate_user_from_token!
     before_action :authenticate_user!
     before_filter :set_current_user
    
    
    
      def set_current_user
    
          Thread.current[:current_user] = current_user
    
      end 
    
    
       private
    
    
      #for authenticating the token 
      def authenticate_user_from_token!
    
        user_id = params[:id].presence
        user       = user_id && User.find_by_id(user_id)
        puts user 
        if user && Devise.secure_compare(user.authentication_token,  params[:auth_token])
          puts "about to sign in"
          sign_in user, store: false
          puts ""
        end
      end
    

    用户控制器:

    class UsersController < ApplicationController
    
     skip_before_filter :verify_authenticity_token,
                     :if => Proc.new { |c| c.request.format == 'application/json' }
    
     skip_before_filter :authenticate_user!
    
    
        def index
    
        end 
    
        def create 
    
            respond_to do |format|
    
                      format.json {
                        if params[:user] && params[:user][:email] && params[:user][:name]# input name and email
                          @user = User.where(:email => params[:user][:email].downcase).first unless User.where(:email => params[:user][:email].downcase).count == 0 
                          if @user.nil?
                            @user = User.new
                            lookup_hash                 = UUIDTools::UUID.random_create.hexdigest  
                            # @user.phone_number          = params[:user][:phone_number]
                            # @user.safe_update(%w[name email ], params[:user])
                             @user.name = params[:user][:name]
                             @user.email = params[:user][:email]
    
                            if params[:user][:specialization]
                                @user.specialization = params[:user][:specialization]
                            end 
                            if params[:user][:password]
                              @user.password              = params[:user][:password]
                              @user.password_confirmation = params[:user][:password]
                            else
                              @user.password              = lookup_hash[0,6]
                              @user.password_confirmation = lookup_hash[0,6]
                            end
                             #we have to  see wether we have to send password through mail or not.
    
    
    
                            #assigning auth_token at the time of registration
                            @user.assign_authentication_token
                            success = @user && @user.save
                            if success && @user.errors.empty?
    
                              # Jobs::Mailer.async.signup_welcome_email(@user.id).commit!
                              #Jobs::Mailer.async.new_invitation_alpha(@user.id,@user.email,@user.password).commit!
    
    
    
                              sign_in(:user, @user)
    
    
                              #if @user.country_code == "IN" && @user.user_persona == "doctor"
                                #show_promo_code = true
                              #end
    
    
    
                              render :status => :ok,
                                     :json => { :success => true,
                                                :info => "Successfully Registered! Please check you email for password",
                                                :data => { :auth_token => @user.authentication_token,
                                                          :id => @user.id.to_s
                                                            } }
    
                            else
                             render :status => :unprocessable_entity,
                                    :json => { :success => false,
                                                :info => @user.errors,
                                                :data => {} }
                            end
                          else
                            render  :status => 409,
                                    :json => { :success => false,
                                                :info => "You are already Registered!",
                                                :data => {} }
                          end
    
                            else
                              render :status => 412, 
                                      :json => { :success => false,
                                                  :info => "User  details are  missing",
                                                  :data => {} }
                            end
                      }
            end
    
        end              
    
    
    end 
    

    routes.rb中:

    Rails.application.routes.draw do
    
       namespace :api do
         namespace :v1 do
          devise_for :users, controllers: { sessions: 
                    'api/v1/users/sessions' }  
     end 
    end 
    
         post '/register' => 'users#create', :as => :register    
         resources :users
         devise_for :users
         resources :preferences
    
    end
    
    
    
    
    
    
    end
    

    会话控制器:

    class Api::V1::Users::SessionsController < Devise::SessionsController
    
      skip_before_action :verify_signed_out_user, :only => [:destroy]
    
     skip_before_filter :require_no_authentication, :only => [ :new, :create, :cancel , :destroy]
     skip_before_filter :verify_authenticity_token,
                         :if => Proc.new { |c| c.request.format == 'application/json' }
      before_filter :ensure_params_exist, :except => [:destroy]
    
      respond_to :json
    
    
      def create
    
                resource = User.find_for_database_authentication(:email => params[:user][:email]) 
                return invalid_login_attempt unless resource if resource.valid_password?(params[:user][:password])
                sign_in(:user, resource) 
                resource.assign_authentication_token
                resource.save!
                render :status => 200,
                :json => {
                           :success => true,
                          :info => "Logged in",
                          :data => { :auth_token => resource.authentication_token,
                                     :id => resource.id.to_s,
                                     :name => resource.name} }
    
      end
    
      # DELETE /resource/sign_out
      def destroy 
        super
        remove_auth_token params[:auth_token]
    
    
      end
    
    
    
      def failure
        render :status => :unauthorized,
               :json => { :success => false,
                          :info => "Login Failed",
                          :data => {} }
      end
    
    
    
      def remove_auth_token token
         if !token.blank?
           user = User.where(authentication_token: token).first
           if !user.nil?
             user.authentication_token = nil 
             user.save!
           end 
         end 
      end 
    
     protected 
    
    
        def ensure_params_exist
          return unless params[:user].blank?
           render :json=>{:message=>"missing user_login parameter"}, 
                          :status=>422 
        end
    
         def invalid_login_attempt 
             render :json=> {:message=>"Error with your login or password"}, 
                          :status=>401 
         end
    
    
    
    end
    

    设计配置:

    Devise.setup do |config|
      ou use your own mailer class
      # with default "from" parameter.
      config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
    
     .
      require 'devise/orm/mongoid'
    
    
      config.case_insensitive_keys = [:email]
    
    
      config.strip_whitespace_keys = [:email]
    
      #
      config.http_authenticatable_on_xhr = false
    
    
      config.skip_session_storage = [:http_auth]
    
      #
      config.stretches = Rails.env.test? ? 1 : 11
    
    
      config.reconfirmable = true
    
      config.expire_all_remember_me_on_sign_out = true
    
      config.password_length = 6..128
    
    
      config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
    
    
      config.reset_password_within = 6.hours
    
    
      config.navigational_formats = ['*/*','*/*', :html , :json]
    
      config.sign_out_via = :delete
    
    
    end
    

0 个答案:

没有答案