【问题标题】:How do I limit access to controller methods to only authenticated users with devise?如何将控制器方法的访问权限限制为只有经过身份验证的用户?
【发布时间】:2021-08-16 17:06:40
【问题描述】:

我有一个基本的设计问题。我已按照指南帮助使用设计和 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 请求的标头中提供。如何配置事务控制器/路由以正确保护每个请求?

这是我的 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

【问题讨论】:

标签: ruby-on-rails devise jwt


【解决方案1】:

您需要做的就是将下面的行添加到您的ApplicationControllerbefore_action :authenticate_user!

如果你想让一些请求传入某个控制器,那么你可以这样做:skip_before_action :authenticate_user!

【讨论】:

  • 我使用了这个建议,它奏效了。澄清一下,我可以像我描述的那样保留路线,只需要资源:交易?谢谢!
  • 我不确定你到底在问什么......,但只要你的控制器继承自ApplicationController,那么行为应该是预期的,所以简短的回答是的,你可以保持这样. @paul88
猜你喜欢
  • 2019-06-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2018-09-09
  • 2016-10-09
  • 1970-01-01
  • 2010-09-21
相关资源
最近更新 更多