我有一个同时使用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
在此Auth控制器中的 Current User
不返回任何内容,但是在我拥有的另一个项目中,如果没有设计,这将正确地返回用户。
是否有一种方法可以重新定义current_user或将其分配给不同的对象以用于使用Knock?
答案 0 :(得分:0)
在您的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