简体   繁体   English

在使用范围和CanCan的多功能时,如何进行RESTful深度链接

[英]How to do RESTful deep linking when using multi-tenency with scopes and CanCan

Background 背景

My application is using Multi-Tenency With Scopes , which basically means many of my models use default_scope to compare the current_tenant.id to a tenant_id column to determine if the current_user is authorized to access that object. 我的应用程序正在使用Multi-Tenency With Scopes ,这基本上意味着我的许多模型使用default_scope将current_tenant.id与tenant_id列进行比较,以确定current_user是否有权访问该对象。

I'm also using CanCan for authorization. 我也在使用CanCan进行授权。

Question: How do I deep link to a particular object for a user who isn't logged into the application yet? 问题:如何为尚未登录应用程序的用户深层链接到特定对象?

General Use Case 一般用例

I want to be able to email a user and say, "This task has been assigned to you. Click here to see the task." 我希望能够通过电子邮件发送给用户并说:“此任务已分配给您。点击此处查看任务。” Then the user would click a link (eg, http://myapp.com/task/15 ) and be taken directly to the task if they are already logged in to the appropriate tenant (that the task belongs to). 然后,用户可以单击链接(例如, http//myapp.com/task/15 ),如果他们已经登录到相应的租户(该任务所属的),则直接进入该任务。 Or, if they're not logged in, they'd be redirected to a Sign In page with a message that says, "Please log in to access this page." 或者,如果他们没有登录,他们将被重定向到登录页面,并显示“请登录以访问此页面”的消息。

Examples 例子

First, an example that behaves as I'd expect: 首先,一个行为与我期望的一样的例子:

If a user is logged out and goes to http://myapp.com/tasks , then CanCan checks to see if the "Guest" user is authorized to go to Tasks#index. 如果用户注销并转到http://myapp.com/tasks ,则CanCan会检查“Guest”用户是否有权转到Tasks#index。 The Guest isn't authorized to do that, so CanCan raises an exception, which I handle by recording the target path and redirecting to a Sign In page with a message to "Please sign in to access this page." 访客未被授权这样做,因此CanCan引发了一个异常,我通过记录目标路径并重定向到登录页面并输入“请登录以访问此页面”来处理该异常。

And here's an example that has me stumped: 这是一个令我难过的例子:

A user is logged out and clicks a link to http://myapp.com/tasks/15 . 用户已注销并单击指向http://myapp.com/tasks/15的链接。 The user will always get a 404 (not found) error because the first thing Rails does is try to find that particular object. 用户将总是得到404(未找到)错误,因为Rails做的第一件事是尝试找到该特定对象。 But since the user is logged out (meaning current_tenant isn't defined), and that Task is for tenant_id == 5, Rails can't find the object and raises an exception. 但是由于用户已注销(意味着未定义current_tenant),并且该任务是针对tenant_id == 5,因此Rails无法找到该对象并引发异常。

Here's the full debug/stacktrace: 这是完整的调试/堆栈跟踪:

INFO -- : Started GET "/tasks/15" for 127.0.0.1 at 2014-12-14 11:16:59 -0500
INFO -- : Processing by TasksController#show as HTML
INFO -- :   Parameters: {"id"=>"15"}
DEBUG -- :   Task Load (0.8ms)  SELECT  "tasks".* FROM "tasks"  WHERE "tasks"."tenant_id" IS NULL AND "tasks"."id" = $1 LIMIT 1  [["id", 15]]
INFO -- : Completed 404 Not Found in 4ms
FATAL -- : 
ActiveRecord::RecordNotFound (Couldn't find Task with 'id'=15 [WHERE "tasks"."tenant_id" IS NULL]):
app/controllers/application_controller.rb:46:in `scope_current_tenant'

And here's the 'scope_current_tenant' method from application_controller: 这是application_controller的'scope_current_tenant'方法:

def scope_current_tenant
  Tenant.current_id = current_tenant.id if current_tenant
  yield
ensure
  Tenant.current_id = nil
end

What I prefer to happen is the same thing that happens when the user tries to access Tasks#index when logged out. 我喜欢发生的事情与用户在注销时尝试访问Tasks#index时发生的情况相同。

Any ideas how to handle this? 任何想法如何处理这个?

It sounds like you need to verify that the user is logged in before trying to find the task. 听起来您需要在尝试查找任务之前验证用户是否已登录。 Do you have a before_action :authenticate_user! 你有一个before_action :authenticate_user! or similar in your TasksController ? 你的TasksController类似的TasksController

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM