ruby-on-rails - 设计和敲击 gem current_user
问题描述
我有一个同时使用 Devise 和 Knock 的应用程序。它正在使用 Devise 为 Active Admin 提供身份验证,而 Knock gem 正在为我的 API 提供身份验证
我遇到的问题是 Knock 似乎找不到current_user
,我相信这很可能是因为我在同一个项目中使用了 Devise。
我有以下设置:
API 控制器
class ApiController < ActionController::API
include Knock::Authenticable
end
用户控制器(用于 API 而非 ActiveAdmin)
module Api
module V1
class UsersController < ApiController
before_action :set_user, only: [:show, :update, :destroy]
# GET /users/1
def show
render json: @user
end
# POST /users
def create
@user = User.new(user_params)
if @user.save
render json: @user.id, status: :created
else
render json: @user.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /users/1
def update
if @user.update(user_params)
render json: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
# DELETE /users/1
def destroy
@user.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
end
end
认证控制器
module Api
module V1
class AuthController < ApiController
def auth
render json: { status: 200, user: current_user }
end
end
end
end
Current User
在这个 Auth 控制器中没有返回任何东西,但是在我拥有的另一个项目中,没有设计,这将正确返回用户。
有没有办法重新定义 current_user 是什么或将其分配给不同的东西以使用 Knock?
解决方案
在你的 ApplicationController 中试试这个
# JWT: Knock defines it's own current_user method unless one is already
# defined. As controller class is cached between requests, this method
# stays and interferes with a browser-originated requests which rely on
# Devise's implementation of current_user. As we define the method here,
# Knock does not reimplement it anymore but we have to do its thing
# manually.
def current_user
if token
@_current_user ||= begin
Knock::AuthToken.new(token: token).entity_for(User)
rescue
nil
end
else
super
end
end
private
# JWT: No need to try and load session as there is none in an API request
def skip_session
request.session_options[:skip] = true if token
end
# JWT: overriding Knock's method to manually trigger Devise's auth.
# When there is no token we assume the request comes from the browser so
# has a session (potentially with warden key) attached.
def authenticate_entity(entity_name)
if token
super(entity_name)
else
current_user
end
end
推荐阅读
- javascript - 如何调用原始数据重塑过程形成,我们可以轻松访问所需的数据?
- javascript - 如何在不影响应用程序性能的情况下搜索包含字符串数组中指定的任何子字符串的元素?
- python - 替换与数据框中特定字符串匹配的值
- asp.net - 尝试写入网络文件夹时出现 ASP.NET 访问被拒绝错误
- file - 为什么 Hashicorp Packer 文件配置器应该使用临时目录?
- node.js - 在 MongoDB (Mongoose) 中导致更新失败的情况
- apache - 在我们访问目录时设置 Apache mod_headers 任何目录?
- computer-science - 有向无环图的最小入度和最大出度之和的值是多少?
- android - Android-检查 API 级别低于 26 的安装包权限
- reporting-services - 在 RDLC 报告中重复整个表格