如何将对控制器方法的访问限制为仅具有设计的经过身份验证的用户?
How do I limit access to controller methods to only authenticated users with devise?
我有一个基本的设计问题。我遵循了一个指南来帮助使用设计和 JWT 进行用户身份验证。现在身份验证有效,我已经开始为应用程序的其他方面创建更多模型和控制器。比如我有一个事务模型和对应的控制器:
class TransactionsController < ApplicationController
def create
transaction = Transaction.new(transaction_params)
if transaction.save
render json: transaction
else
render json: { errors: "transaction is invalid" }, status: :unprocessable_entity
end
end
def index
transactions = Transaction.all.order(created_at: :desc)
render json: transactions
end
def destroy
transaction = Transaction.find(params[:id])
transaction&.destroy
render json: { message: "transaction deleted"}
end
def transaction_params
params.require(:transaction).permit(:payer_id, :recipient_id, :amount)
end
end
我像这样将它添加到路由中:
Rails.application.routes.draw do
devise_for :users,
controllers: {
registrations: :registrations,
sessions: :sessions
}
resources :transactions
root 'homepage#index'
get '/*path' => 'homepage#index'
end
在使用 Postman 进行测试时,基本的事务 CRUD 方法可以工作,但问题是它们不应该只在提供身份验证令牌时才工作吗?我相信这是基于令牌的身份验证的要点,每个 api 请求都会在 header 中提供令牌。如何配置事务 controller/routes 以正确保护每个请求?
这是我的ApplicationController供参考:
class ApplicationController < ActionController::API
respond_to :json
before_action :process_token
def authenticate_user!(options = {})
head :unauthorized unless signed_in?
end
def signed_in?
@current_user_id.present?
end
def current_user
@current_user ||= super || User.find(@current_user_id)
end
def process_token
if request.headers['Authorization'].present?
begin
jwt_payload = JWT.decode(request.headers['Authorization'].split(' ')[1].remove('"'), Rails.application.secrets.secret_key_base).first
@current_user_id = jwt_payload['id']
rescue JWT::ExpiredSignature, JWT::VerificationError, JWT::DecodeError
head :unauthorized
end
end
end
end
您需要做的就是将以下行添加到您的 ApplicationController
:before_action :authenticate_user!
如果你想让一些请求传入某个控制器那么你可以这样做:skip_before_action :authenticate_user!
我有一个基本的设计问题。我遵循了一个指南来帮助使用设计和 JWT 进行用户身份验证。现在身份验证有效,我已经开始为应用程序的其他方面创建更多模型和控制器。比如我有一个事务模型和对应的控制器:
class TransactionsController < ApplicationController
def create
transaction = Transaction.new(transaction_params)
if transaction.save
render json: transaction
else
render json: { errors: "transaction is invalid" }, status: :unprocessable_entity
end
end
def index
transactions = Transaction.all.order(created_at: :desc)
render json: transactions
end
def destroy
transaction = Transaction.find(params[:id])
transaction&.destroy
render json: { message: "transaction deleted"}
end
def transaction_params
params.require(:transaction).permit(:payer_id, :recipient_id, :amount)
end
end
我像这样将它添加到路由中:
Rails.application.routes.draw do
devise_for :users,
controllers: {
registrations: :registrations,
sessions: :sessions
}
resources :transactions
root 'homepage#index'
get '/*path' => 'homepage#index'
end
在使用 Postman 进行测试时,基本的事务 CRUD 方法可以工作,但问题是它们不应该只在提供身份验证令牌时才工作吗?我相信这是基于令牌的身份验证的要点,每个 api 请求都会在 header 中提供令牌。如何配置事务 controller/routes 以正确保护每个请求?
这是我的ApplicationController供参考:
class ApplicationController < ActionController::API
respond_to :json
before_action :process_token
def authenticate_user!(options = {})
head :unauthorized unless signed_in?
end
def signed_in?
@current_user_id.present?
end
def current_user
@current_user ||= super || User.find(@current_user_id)
end
def process_token
if request.headers['Authorization'].present?
begin
jwt_payload = JWT.decode(request.headers['Authorization'].split(' ')[1].remove('"'), Rails.application.secrets.secret_key_base).first
@current_user_id = jwt_payload['id']
rescue JWT::ExpiredSignature, JWT::VerificationError, JWT::DecodeError
head :unauthorized
end
end
end
end
您需要做的就是将以下行添加到您的 ApplicationController
:before_action :authenticate_user!
如果你想让一些请求传入某个控制器那么你可以这样做:skip_before_action :authenticate_user!