use*_*745 2 ruby-on-rails cancan cancancan ruby-on-rails-6
我注意到用户可以访问他们不应该访问的操作。
我在 Rails 控制台中用类似的东西进行了调试
user = User.first
physician = Physician.first
ability = Ability.new(user)
ability.can?(:send_message, physician)
# => false
Run Code Online (Sandbox Code Playgroud)
上面说用户无法访问该医生的 send_message 操作,这是所需的行为,但我知道他们可以在应用程序中!
我认为这缩小了 cancancan 由于某种原因加载错误模型实例的问题的原因。cancan 文档中也暗示了这一点:
注意:这假设模型实例已正确加载。
但问题是我不确定如何从这里诊断问题,因为控制台说它应该可以工作。我不知道如何查看cancancan设置的模型实例,也不知道还能尝试什么。
有任何想法吗?
我确实设法通过authorize! :send_message, physician在控制器中使用来解决这个问题,但由于我只是偶然发现了这种行为,我认为弄清楚为什么加载了错误的模型实例更为重要(特别是这样我可以看看这是否是其他地方也发生过)。
我认为发生这种情况是因为我有很多自定义操作,有些有@physician = Physician.find(current_user.physician.id)(即他们是当前用户),而其他则更像是@physician = Physician.find_by_id(physician_params[:id]). 我不确定cancan如何设置实例模型,但我知道它不是通灵的,所以它不知道是否将其设置为当前用户的医生实例,或者传入的医生id的医生实例。
cancancan 如何为自定义方法设置模型实例(我认为它会尝试一些方法,如果不起作用,则尝试其他方法,等等)?
有帮助的小注释:
load_and_authorize_resource 确实尝试加载模型实例以进行非 RESTful 操作当我返回鼻涕虫时,它打破了这种行为,我可以编辑所有神奇宝贝。
在这里留下我的笔记,以防对其他人有帮助。
TL;DR,cancancan 做出了很多微妙的假设,而你从一开始就不会知道这些假设。我通过仔细阅读 cancancan自述文件、代码和定义能力文档中的注释发现了其中的许多内容。
所以这里...
authorize!控制器操作本身,cancancan 将在每个控制器操作中查找实例变量。load_and_authorize_resource在控制器的开头添加,则会做两件事:
load_and_authorize_resource仍会尝试加载模型实例,但它如何知道要加载什么?它猜测,对我来说,我不喜欢这一点,所以要注意这一点。
load_and_authorize_resource,因此我确切地知道发生了什么。
load_and_authorize_resource 之后load_and_authorize_resource应该始终在设置模型实例变量的任何之前操作之后实例变量的名称取决于操作。如果我们有一个文章控制器,那么:
load_and_authorize_resource检查模型实例是否已设置,如果没有,则设置 1。因此,如果您有一个创建 @article/@articles 的 before 操作,则load_and_authorize_resource不会为您执行此操作(即它不会覆盖它),但如果您没有设置,cancan 将尝试设置一个。查看源码中的注释:
如果实例变量已设置,则不会加载资源。这使得通过某些操作的 before_action 可以轻松地覆盖行为。
current_user在ability.rb中使用,它会默默地出错(!!),所以一定要使用user:)| 归档时间: |
|
| 查看次数: |
1215 次 |
| 最近记录: |