Rails Admin未通过Cancancan或Devise进行身份验证

时间:2019-04-22 02:14:45

标签: ruby-on-rails devise rails-admin cancancan

我在配置中尝试过此操作

TCP    xxx.xx.xx.xx:1099      xx.xx.xx.xxx:443      ESTABLISHED     2222

在这里,访问taskkill /F /PID 2222 会使我陷入登录循环。我登录然后重定向到登录页面。

以前我曾经尝试过

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

在rails admin配置中使用CanCanCan身份验证。这导致用户始终为零。即使我放进去

/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?

我被困在重定向回登录中。

路线:

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

在ApplicationController中:

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

对此进行了尝试,current_user为零。

2 个答案:

答案 0 :(得分:0)

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

默认情况下,它首先尝试在会话中找到有效的resource_return_to密钥,然后回退到resource_root_path,否则将使用根路径。对于用户范围,您可以通过以下方式定义默认网址:

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

答案 1 :(得分:0)

用于重定向的控制器逻辑

Guillermo Siliceo Trueba中的解决方案不适用于您的Users::SessionsController#create操作,因为您没有通过关键字super来调用the parent class create action

来自类create的方法Devise::SessionsController将在最后一行运行respond_with,并将after_sign_in_path_for(resource)返回的值用作location

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的{​​{1}},则执行.json之间的代码,如果format.json do .. endrequest到达,则父方法为称为(我涵盖了您的所有情况)。

Rails路由器从附加在网址末尾的format.html.json中识别请求格式(例如GET .html

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 请求将被路由to the super create action。您只需要覆盖父级的I am doing in my ApplicationController方法html

def after_sign_in_path_for(resource),然后从此方法中仅if resource.admin,然后跳过其他行,否则按照正常行为并调用super#after_sign_in_path_for(resource)

return rails_admin_url

身份验证错误消息

def after_sign_in_path_for(resource) return rails_admin_url if resource.admin super end 将错误消息保存在warned.authenticate!中。您只需要使用self.resource.errors在设备上显示错误并在前端中处理响应即可。

我正在SignInScreen Component

中渲染它们

enter image description here

令牌认证

json_response[:error]

我使用simple_token_authentication for devise,它也允许您regenerate the token every time the user signs in

您只需安装gem并添加acts_as_token_authenticatable inside your user model

user.generate_auth_token
user.save

您将标题class User < ApplicationRecord acts_as_token_authenticable end X-User-Email传递给相应的值,如in their guide所述。

其他alternatives to simple_token_authentication