簡體   English   中英

Rails Admin未通過Cancancan或Devise進行身份驗證

[英]Rails Admin not authenticating with Cancancan or Devise

我在配置中嘗試了這個:

  ### Popular gems integration
  config.authenticate_with do
    warden.authenticate! scope: :user
  end
  config.current_user_method(&:current_user)

在這里,訪問/admin會使我陷入登錄循環中。 我登錄然后重定向到登錄頁面。

以前我嘗試過

class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
      user ||= User.new # guest user (not logged in)
      if user.admin?

在rails admin配置中使用CanCanCan身份驗證。 這導致用戶始終為零。 即使我放進去

config.current_user_method(&:current_user)

如何解決此問題以驗證是否是管理員?

編輯:在會話控制器中

      if user.admin
        redirect_to rails_admin_url
      else
        render json: user
      end

而我陷入了重新登錄的重定向中。

路線:

Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  devise_for :users, controllers: { sessions: :sessions },
                      path_names: { sign_in: :login }
... then many resources lines

編輯:

會話控制器:

class SessionsController < Devise::SessionsController
  protect_from_forgery with: :null_session

  def create
    user = User.find_by_email(sign_in_params[:email])
    puts sign_in_params
    if user && user.valid_password?(sign_in_params[:password])
      user.generate_auth_token
      user.save
      if user.admin
        redirect_to rails_admin_url
      else
        render json: user
      end
    else
      render json: { errors: { 'email or password' => ['is invalid'] } }, status: :unprocessable_entity
    end
  end
end

Rails管理員配置,請嘗試以下操作:

  ### Popular gems integration
  config.authenticate_with do
    redirect_to merchants_path unless current_user.admin?
  end
  config.current_user_method(&:current_user)

在ApplicationController中:

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  helper_method :current_user

試過這個,current_user為nil。

您可能需要在ApplicationController上定義after_sign_in_path_for方法

默認情況下,它首先嘗試在會話中找到有效的resource_return_to密鑰,然后回退到resource_root_path,否則它將使用根路徑。 對於用戶范圍,可以通過以下方式定義默認url:

get '/users' => 'users#index', as: :user_root # creates user_root_path

namespace :user do
  root 'users#index' # creates user_root_path
end

如果未定義資源根路徑,則使用root_path。 但是,如果此默認值還不夠,則可以對其進行自定義,例如:

def after_sign_in_path_for(resource)
  stored_location_for(resource) ||
    if resource.is_a?(User) && resource.can_publish?
      publisher_url
    else
      super
    end
end

重定向控制器邏輯

Guillermo Siliceo Trueba的解決方案不適用於您的Users::SessionsController#create操作,因為您沒有通過關鍵字super調用父類create操作

該方法create從類Devise::SessionsController運行respond_with使用在上線location ,從返回的值after_sign_in_path_for(resource)

class Devise::SessionsController < DeviseController
  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, location: after_sign_in_path_for(resource)
  end
end

我在我的Users::SessionsController使用此解決方案來處理htmljson請求,您可以實現相同的解決方案。

如果控制器接收到該request與格式.json ,之間的代碼format.json do .. end被執行時,如果request與到達format.html父方法被稱為(I涵蓋所有的場景)。

Rails路由器從URL末尾附加的.json.html識別請求格式(例如GET https://localhost:3000/users.json

class Users::SessionsController < Devise::SessionsController
  def create
    respond_to do |format|
      format.json do 
        self.resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#new")
        render status: 200, json: resource
      end
      format.html do 
        super
      end
    end
  end
end

html請求將被路由super創建動作 您只需要像我在ApplicationController所做的那樣,從父類重寫方法def after_sign_in_path_for(resource)

if resource.admin則只需從此方法return rails_admin_url並跳過其他行,否則按照正常行為並調用super#after_sign_in_path_for(resource)

def after_sign_in_path_for(resource)
  return rails_admin_url if resource.admin
  super
end

認證錯誤信息

warned.authenticate! 將保存在self.resource.errors內部的錯誤消息。 您只需要使用json_response[:error]在設備上顯示錯誤並在前端中處理響應即可。

我在SignInScreen組件中渲染它們

在此處輸入圖片說明

令牌認證

user.generate_auth_token
user.save

我使用simple_token_authentication進行設計 ,這也使您每次用戶登錄時都可以重新生成令牌

您只需安裝gem並user模型中添加acts_as_token_authenticatable

class User < ApplicationRecord
   acts_as_token_authenticable
end

您按照標頭指南中的說明傳遞標頭X-User-EmailX-User-Token

simple_token_authentication其他替代方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM