首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >授权和构造RESTful后端的正确方法是什么?

授权和构造RESTful后端的正确方法是什么?
EN

Stack Overflow用户
提问于 2013-02-28 13:52:35
回答 4查看 3.9K关注 0票数 7

很多关于Web的例子都没有考虑到今天许多应用程序都是多用户的问题。

假设一个多用户后端公开了一个RESTful API。后端数据体系结构使用共享数据库和共享模式。每个表将包含对tenant_id的引用。

代码语言:javascript
复制
+-------------+----+-----------------+
|  tenant_name| id |   shared_secret |
+-------------+----+-----------------+
|         bob |  1 |   2737sm45sx543 |
+-------------+----+-----------------+
|       alice |  2 |   2190sl39sa8da |
+-------------+----+-----------------+

+-------------+----+-------+-----------+
|    pet_name | id |  type | tenant_id |
+-------------+----+-------+-----------+
|       fuffy |  1 |   dog |         1 |
+-------------+----+-------+-----------+
|       kerry |  2 |   cat |         2 |
+-------------+----+-------+-----------+

问题1:当三个或更多客户端应用程序(即Android、iOS和Web )与RESTful后端交互时,您将如何对后端执行身份验证?

代码语言:javascript
复制
RESTful backend, API, HTTP-Verbs, shared database and schema 
|
|
+---- Web Application (Client 1)
|     |
|     + Alice
|     |
|     + Bob
|
+---- Android Application (Client 2)
|     |
|     + Alice
|     |
|     + Bob
|
+---- iOS Application (Client 3)
|     |
|     + Alice
|     |
|     + Bob
|

每个客户都应该允许Alice和Bob管理她/他的宠物。每个客户端都是一个GUI,它将使用(内部,发出HTTP请求)作为后端。问:每个客户端如何对后端进行身份验证?

假设HMAC (完全是RESTful,没有会话):此方法涉及使用共享秘密(从未通过线路发送)对有效负载进行签名。每个客户端是否应该拥有自己的tenant表副本(该表包含shared_secret字段)?

代码语言:javascript
复制
Android App -> Client Sign -> Signed Request -> Backend -> Result
    Web App -> Client Sign -> Signed Request -> Backend -> Result

问题2:资源URI的外观应该是什么样子?

以下是获取Bob宠物的两种可能方法:

可能性#1:Authorization头给出了租户的(唯一)名称:

代码语言:javascript
复制
GET /pets HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz

tenant_id作为查询参数发送:

代码语言:javascript
复制
GET /pets/tenant_id=1 HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-03-08 03:01:06

第1部分

(大声地想:你已经决定使用HTTP和HMAC了吗?如果是的话,你为什么要问我们?

我建议HTTPS与基本八月。很简单。毕竟,对于条带来说,这已经足够了。

参考文献:

Update:以下是关于如何处理auth的其他详细信息:

  1. 每个客户端应用程序将使用一个API密钥与服务联系。使用HTTPS和Basic,客户端将提供其API密钥作为基本的Auth用户名。它不需要提供密码,因为它使用的是HTTPS。您需要为每个应用程序(Web、Android )分配一个API密钥,我看到了两种方法: 一种选择是为每个用户提供一个在客户端之间共享的API密钥。 B.另一种选择是给每个客户端一个独特的应用程序。)
  2. 但你怎么才能拿到客户的钥匙呢?构建一个“键请求”API端点。我建议为每个客户端提供一个只用于与此端点联系的“启动”密钥。(启动器密钥不授予其他访问权限。)当用户首次使用客户端时,他/她必须进行身份验证。客户端将其传递给“密钥请求”端点,以便生成与用户关联的密钥。从那时起,每个客户端都有一个客户端绑定的API密钥.

第2部分

考虑给每个租户一个子域。如果您使用Rails (或者任何现代的web堆栈),您可以使用子域来查找租户id。然后您的API可以像这样使用:

代码语言:javascript
复制
GET http://tenant1.app.co/pets
GET http://tenant2.app.co/pets
GET http://tenant3.app.co/pets

参考资料(Rails特有的,但应该有助于跨web堆栈):

  • 用Rails编写多租户应用程序
  • 租客
  • Rails中的多租户

注意:正如您的例子所示,为了简单起见,我不会对不同的租户重复使用相同的宠物id。例如,下面是一个简单的方法:

代码语言:javascript
复制
GET http://tenant1.app.co/pets/200
GET http://tenant2.app.co/pets/201
GET http://tenant3.app.co/pets/202

我所描述的方法比将tenant_id作为查询参数传递要干净得多。此外,使用tenant_id作为参数也是错误的。我喜欢为更多的“算法”使用参数,正如我在Richardson在"RESTful网络服务“中所读的那样。

参考文献:

  • 多租户数据库体系结构.第5部分
  • “查询字符串参数是适当的,如果它们是对资源的输入,否则,这些值应该移到URI中”- 面向资源的维基百科体系结构
票数 4
EN

Stack Overflow用户

发布于 2013-03-04 17:03:33

您所说的“多租户”是指应用程序/web服务用户吗?多租户通常意味着更复杂的msdn.microsoft.com/en-us/library/aa479086.aspx

您需要使用web服务对每个用户进行身份验证。这可以通过SSL的基本http身份验证来完成。

从web服务的角度来看,您将对所有三个客户端执行相同的身份验证。服务并不关心客户端的类型--这才是重点。您可能需要对客户端进行不同的表示,例如XHTML或JSON。我喜欢保持简单,并且总是选择JSON。

对于资源,最简单的管理方法是将用户资源作为顶级资源,然后将每个用户的所有资源链接在一起。

代码语言:javascript
复制
GET users/fred/pets - returns all pets for user fred
GET users/fred/pets/sparky - returns details on freds pet sparky

这样做的好处是,您可以添加代码来授权每个请求,例如,您可能有两个用户,fred和jack。这两个用户都将通过身份验证,但是您应该只允许fred请求他的资源,jack只允许他请求他的资源。您只需在api中添加授权检查,例如从URI获取用户名,获取经过身份验证的用户的用户名,检查它们是否相同。如果不返回类似http 403禁止的内容,如果它们相同,则允许请求。

我想如果你还不清楚的话,你需要读一读休息的细节。到目前为止,关于这一主题的最好的书是这本RESTful网络服务。它涵盖了基本原则的休息。它也有一个非常好的部分设计资源,以及如何管理用户和多个客户端。

票数 3
EN

Stack Overflow用户

发布于 2013-03-04 19:04:09

我不太明白这个问题,因为在这种情况下,多租户似乎有点过火了。不过,我可以尝试回答第二个问题。

REST是一种“基于资源的”体系结构,您必须认识到/pets/pets/?tenant=1并不是指相同的资源:

  • /pets是指当前用户的宠物,
  • /pets/?tenant=1指的是鲍勃的宠物。

虽然这两种解决方案都是错误的,但通常最好是得到第二种解决方案。URI确实是为共享而设计的,您有更多的理由共享“Bob的宠物”(即使它需要身份验证和授权才能被表示),而不是抽象的“我的宠物”,这对于每个用户来说都是不同的。

类似的讨论请参见资源in是否应该存在于urls中? ..。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15137244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档