我正在使用Devise为大多数用户身份验证工作实施Rails应用。我注意到的一件事是,在为安全敏感任务传递标识符时,他们总是使用查询字符串参数完成。
例如,发送给用户的密码重置电子邮件中包含的URL可能如下所示:
http://example.com/users/password/edit?reset_password_token=_aPKoNpLHm7HYs_o4Qex
Devise根据reset_password_token
查找用户,并在用户重置表单时更改密码。
我刚刚实现了一个类似的功能,不是由Devise处理的。在每封电子邮件中,我都包含取消订阅链接。控制器根据唯一令牌查找用户,并将其unsubscribe标志设置为true,即使用户未登录也是如此。
但是,我生成的URL如下所示:
http://example.com/subscription/3e7eb22a268b62d5/edit
这基本上与Devise正在做的事情相同。不同之处在于我将令牌包含在URL路径本身而不是查询字符串中。
在我看来,这更加RESTful,因为它指向用户随后更新的特定资源(相关订阅)(通过将表单发布到PUT http://example.com/subscription/3e7eb22a268b62d5
)。除了这个好处之外,我不认为这两种方法有任何区别。
在RESTful URL上使用查询字符串参数是否缺少某些原因?
答案 0 :(得分:2)
我是否缺少使用查询字符串参数的原因 通过RESTful URL?
不是真的。用户和查询参数之间唯一真正的区别是,某些干预系统可能不会使用查询参数来缓存URI,因此在这种情况下,在基础URI中嵌入标识符是一种解决方法。
那就是说,这个论点与你的用例几乎无关。
在高层次上,REST完全不关心,因为它将URI视为一个整体(并且查询参数是URI的一部分)。所以,它对此事没有任何建议。两个URI都唯一地“命名资源”,因此REST很高兴。
习惯上,在BASE URI中嵌入id非常受欢迎,它可能与边缘案例缓存场景相关,因此,这是唯一真正的粉丝挥舞着该表单的标志与查询参数。
在美容方面,许多人更喜欢嵌入式。
我会让你权衡这些考虑因素。
答案 1 :(得分:-1)
在RESTful服务中,在URL中传递令牌并不是很好。更好的方法是在请求内容中发送它。也就是说,这个令牌是一次性的,并没有真正与身份验证相关,所以它可能有点不那么讨厌......而且我想这个功能需要从链接(在电子邮件中)而不是从表单到达提交,这就是使用这种URL参数的原因。
否则,诚实地在资源路径(edit
)中使用操作(元素http://example.com/subscription/3e7eb22a268b62d5/edit
)并不真正RESTful ;-)实际上,该操作由使用的方法本身描述。对于方法POST
,如果您想支持多个操作,我们最终还可以使用其他提示。
关于方法PUT
的使用,当您想要更新资源的完整表示时,应该使用它。在您的情况下,我认为您更倾向于方法POST
,因为您希望使用重置密码令牌对订阅执行操作(重置订阅的密码)。以下是我将在您的案例中看到的请求:
POST http://example.com/subscription/3e7eb22a268b62d5
{
"reset_password_token": "_aPKoNpLHm7HYs_o4Qex"
}
我为您提供了两个可以帮助您设计请求的链接:
根据Craig Walker的评论编辑。
希望它可以帮到你, 亨利