很多关于Web的例子都没有考虑到今天许多应用程序都是多用户的问题。
假设一个多用户后端公开了一个RESTful API。后端数据体系结构使用共享数据库和共享模式。每个表将包含对tenant_id的引用。
+-------------+----+-----------------+
| 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后端交互时,您将如何对后端执行身份验证?
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字段)?
Android App -> Client Sign -> Signed Request -> Backend -> Result
Web App -> Client Sign -> Signed Request -> Backend -> Result问题2:资源URI的外观应该是什么样子?
以下是获取Bob宠物的两种可能方法:
可能性#1:Authorization头给出了租户的(唯一)名称:
GET /pets HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUztenant_id作为查询参数发送:
GET /pets/tenant_id=1 HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz发布于 2013-03-08 03:01:06
第1部分
(大声地想:你已经决定使用HTTP和HMAC了吗?如果是的话,你为什么要问我们?
我建议HTTPS与基本八月。很简单。毕竟,对于条带来说,这已经足够了。
参考文献:
Update:以下是关于如何处理auth的其他详细信息:
第2部分
考虑给每个租户一个子域。如果您使用Rails (或者任何现代的web堆栈),您可以使用子域来查找租户id。然后您的API可以像这样使用:
GET http://tenant1.app.co/pets
GET http://tenant2.app.co/pets
GET http://tenant3.app.co/pets参考资料(Rails特有的,但应该有助于跨web堆栈):
注意:正如您的例子所示,为了简单起见,我不会对不同的租户重复使用相同的宠物id。例如,下面是一个简单的方法:
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网络服务“中所读的那样。
参考文献:
发布于 2013-03-04 17:03:33
您所说的“多租户”是指应用程序/web服务用户吗?多租户通常意味着更复杂的msdn.microsoft.com/en-us/library/aa479086.aspx。
您需要使用web服务对每个用户进行身份验证。这可以通过SSL的基本http身份验证来完成。
从web服务的角度来看,您将对所有三个客户端执行相同的身份验证。服务并不关心客户端的类型--这才是重点。您可能需要对客户端进行不同的表示,例如XHTML或JSON。我喜欢保持简单,并且总是选择JSON。
对于资源,最简单的管理方法是将用户资源作为顶级资源,然后将每个用户的所有资源链接在一起。
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网络服务。它涵盖了基本原则的休息。它也有一个非常好的部分设计资源,以及如何管理用户和多个客户端。
发布于 2013-03-04 19:04:09
我不太明白这个问题,因为在这种情况下,多租户似乎有点过火了。不过,我可以尝试回答第二个问题。
REST是一种“基于资源的”体系结构,您必须认识到/pets和/pets/?tenant=1并不是指相同的资源:
/pets是指当前用户的宠物,/pets/?tenant=1指的是鲍勃的宠物。虽然这两种解决方案都是错误的,但通常最好是得到第二种解决方案。URI确实是为共享而设计的,您有更多的理由共享“Bob的宠物”(即使它需要身份验证和授权才能被表示),而不是抽象的“我的宠物”,这对于每个用户来说都是不同的。
类似的讨论请参见资源in是否应该存在于urls中? ..。
https://stackoverflow.com/questions/15137244
复制相似问题