[英]CanCanCan not allowing access to endpoints which returns all records
我正在嘗試為我在 Rails 中構建的 API 配置授權。 授權似乎有效,但不適用於返回資源所有記錄的端點。 這些端點也恰好是在config/routes.rb
的資源塊之外創建的(不確定這是否是解釋這一點的正確方法)。
例如:當我 go 到以下端點時,如果有數據,我會收到 200 HTTP 響應;如果記錄不存在,則會收到 204 HTTP 響應:
http://localhost:3000/v1/resources/venues/zoom
但是當我 go 到以下端點時,我收到授權錯誤:
http://localhost:3000/v1/resources/venues/all
這是我的config/routes.rb
文件:
Rails.application.routes.draw do
# Private Messaging
resources :conversations, only: [:index, :create]
resources :messages, only: [:create]
mount ActionCable.server => '/cable'
# Admin
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
namespace :v1 do
namespace :resources do
# Users
post '/users/:id/avatar/upload' => 'users#upload_avatar'
patch '/users/:id/avatar/update' => 'users#update_avatar'
put '/users/:id/avatar/update' => 'users#update_avatar'
delete '/users/:id/avatar/delete' => 'users#delete_avatar'
namespace :users do
get ':id' => :show
end
# Venue Types
get '/venue_types/all' => 'venue_types#all'
post '/venues/:name/images/upload' => 'venues#upload_images'
namespace :venue_types do
get ':name' => :show
patch ':name' => :update
put ':name' => :update
delete ':name' => :delete
post 'new'
end
# Attributes
get '/attribute_defaults/all' => 'attribute_defaults#all'
namespace :attribute_defaults do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
# Venues
get '/venues/all' => 'venues#all'
namespace :venues do
get ':name' => :show
patch ':name' => :update
put ':name' => :update
delete ':name' => :delete
post 'new'
end
# Venue Attributes
get '/venue_attributes/all' => 'venue_attributes#all'
namespace :venue_attributes do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
# Bids
get '/bids/all' => 'bids#all'
namespace :bids do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
# Bookings
get '/bookings/all' => 'bookings#all'
namespace :bookings do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
# Venue Ratings
get '/venue_ratings/all' => 'venue_ratings#all'
namespace :venue_ratings do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
# User Ratings
get '/user_ratings/all' => 'user_ratings#all'
namespace :user_ratings do
get ':id' => :show
patch ':id' => :update
put ':id' => :update
delete ':id' => :delete
post 'new'
end
end
end
# Auth
devise_for :users,
path: 'auth',
path_names: {
sign_in: 'login',
sign_out: 'logout',
registration: 'register'
},
controllers: {
sessions: 'sessions',
registrations: 'registrations',
confirmations: 'confirmations'
}
end
這是我的app/models/ability.rb
文件:
# frozen_string_literal: true
class Ability
include CanCan::Ability
def initialize(user)
# Admin
if user.present? && user.is_admin?
can :manage, :all
# Host
elsif user.present? && user.is_host?
can :manage, User, id: user.id
can [:read, :write, :update], [Venue, VenueAttribute, Bid, UserRating, VenueRating]
can [:read], User
can :destroy, [Venue, VenueAttribute]
# Guest
elsif user.present? && user.is_guest?
can :manage, User, id: user.id
can [:write, :update], [Bid, VenueRating], id: user.id
can [:write, :update], [UserRating], rated_by: user.id
can :read, Bid, id: user.id
can :read, [Venue, User, VenueRating, UserRating]
# No role
else
can :read, [Venue, User, UserRating, VenueRating]
end
end
end
這是我的app/controllers/v1/resources/venues_controller.rb
文件:
class V1::Resources::VenuesController < ActionController::API
load_and_authorize_resource param_method: :venue_params
respond_to :json
before_action :authenticate_user!, except: [:all, :show]
before_action :set_venue, except: [:all, :new]
# GET /v1/resources/venues/all
def all
@venues = Venue.all.where(is_published: true, is_expired: false)
if !@venues.empty?
render json: @venues, methods: :image_urls, status: :ok
else
head :no_content
end
end
# POST /v1/resources/venues/new
def new
@venue = Venue.new(venue_params)
if @venue.save
render json: @venue, status: :created
else
render json: @venue.errors, status: :unprocessable_entity
end
end
# GET /v1/resources/venues/:name
def show
if @venue
render json: @venue, methods: :image_urls, status: :ok
else
head :no_content
end
end
# PATCH/PUT /v1/resources/venues/:name
def update
if @venue.update(venue_params)
render json: @venue, status: :ok
else
render json: @venue.errors, status: :unprocessable_entity
end
end
# DELETE /v1/resources/venues/:name
def delete
@venue.destroy
head :no_content
end
# POST /v1/resources/venues/:name/images/upload
def upload_images
@venue.images.attach(params[:images])
render json: @venue, methods: :image_urls, status: :ok
end
private
# Use callbacks to share common setup or constraints between actions.
def set_venue
@venue = Venue.find_by(name: params[:name])
end
# Never trust parameters from the scary internet, only allow the white list through.
def venue_params
params.require(:venue).permit(:name, :price, :minimum_bid, :is_published, :currency, :is_expired, :location, :venue_type_id, :user_id, images: [])
end
end
app/controllers/application_controller.rb
文件中沒有額外的代碼。
知道如何調試這個問題嗎? 另外,我如何授予未經身份驗證的用戶訪問權限? 我希望沒有帳戶的用戶能夠瀏覽場地。
首先,將load_and_authorize_resource
更改為authorize_resource
因為您是手動加載它。 在all
操作中手動授權。
class V1::Resources::VenuesController < ActionController::API
authorize_resource param_method: :venue_params
skip_authorize_resource only: :all
respond_to :json
before_action :authenticate_user!, except: [:all, :show]
before_action :set_venue, except: [:all, :new]
# GET /v1/resources/venues/all
def all
@venues = Venue.all.where(is_published: true, is_expired: false)
authorize! :read, Venue
if !@venues.empty?
render json: @venues, methods: :image_urls, status: :ok
else
head :no_content
end
end
end
添加到能力.rb
if user.nil?
can :read, Venue
使其適用於未經過身份驗證的用戶
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.