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

Web services 授权和构造RESTful后端的正确方法是什么,web-services,api,rest,authorization,restful-authentication,Web Services,Api,Rest,Authorization,Restful Authentication,关于RESTfulWeb服务的许多示例没有考虑到当今许多应用程序都是多用户的问题 设想一个多用户后端公开一个RESTful API。后端数据体系结构使用共享数据库和共享模式。每个表将包含对租户id的引用: +-------------+----+-----------------+ | tenant_name| id | shared_secret | +-------------+----+-----------------+ | bob | 1 | 2737sm4

关于RESTfulWeb服务的许多示例没有考虑到当今许多应用程序都是多用户的问题

设想一个多用户后端公开一个RESTful API。后端数据体系结构使用共享数据库和共享模式。每个表将包含对
租户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 App)与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请求)后端。问题:每个客户端如何能够针对后端进行身份验证

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
|
假设HMAC(它是完全RESTful的,没有会话):此方法涉及使用共享密钥对有效负载进行签名(从不通过线路发送)。每个客户端是否都应该拥有自己的
租户
表副本(该表包含
共享的\u秘密
字段)

问题2:资源URI应该是什么样子

以下是获得Bob宠物的两种方法:

可能性#1:
授权
标题给出了承租人的(唯一)名称:

可能性#2。
租户id
作为查询参数发送:

GET /pets/tenant_id=1 HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz

“多租户”是指应用程序/web服务用户吗?多租户通常意味着更复杂的事情

您需要使用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获取用户名,获取经过身份验证的用户的用户名,检查它们是否相同。如果不返回类似HTTP403的禁止,如果它们相同,则允许请求


我想如果你还不清楚的话,你需要仔细阅读其余部分的细节。到目前为止,关于这个问题最好的书是这本。它涵盖了第一原则的其余部分。它还有一个关于设计资源以及如何管理用户和多个客户端的非常好的部分。

我不确定是否理解这个问题,因为在这种情况下,多租户似乎有点过分了。 不过,我可以试着回答第二个问题

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

  • /pets
    指当前用户的宠物
  • /pets/?tenant=1
    指鲍勃的宠物
虽然两种解决方案都不对,但通常最好得到第二种解决方案。URI确实是为了共享而设计的,与抽象的“我的宠物”相比,您有更多的理由共享“Bob的宠物”(即使它需要身份验证和授权来表示),因为抽象的“我的宠物”对于每个用户都是不同的


有关类似的讨论,请参见…

如果HTTP是所有3种客户端类型都使用的协议,您应该只需要实现一个身份验证方案。你可以选择你的毒药-,或者是一些常用的方法。因为它是通过HTTP的,所以我认为没有理由复制这种逻辑。根据您的平台,可能有几个框架可以为您抽象这一点

要区分客户端类型,可以使用HTTP头
用户代理
可能已经使这成为可能。另一个选项是使用您定义的自定义标题。任何HTTP客户端都可以设置头,任何服务器都可以处理自定义头。一个像样的web框架将使您相对轻松地获得这些信息。作为一种后端服务,我想您可能希望统一处理所有客户端请求,或者尽可能多地处理。当然,维护一个后端比维护三个后端更好

至于您的API应该是什么样子,完全取决于您。为了保持安静,这是非常值得的阅读插入强制性链接。很有可能,你真正想要的是一本写“足智多谋”链接的指南


在您列出的选项中,如果用户可能需要访问系统中的所有宠物,则首选第二个选项,
/pets?userId=bob
。如果用户只需要访问他们的宠物,则首选第一个,
/pets

第1部分

(大声思考:您是否已经决定使用HTTP和HMAC?如果是,为什么要问我们?)

我建议使用带有基本身份验证的HTTPS。简单。毕竟,这对我来说已经足够好了

参考资料:

  • 有关HMAC与备选方案的比较,请参见
  • “SSL只在Web服务器(任何内部路由、服务器日志记录等)看到明文密码之前提供保护。”
更新:以下是有关如何处理身份验证的一些附加详细信息:

  • 每个客户端应用程序都将使用API密钥与服务联系。使用HTTPS和基本身份验证,客户端将提供其API密钥作为基本身份验证用户名。它不需要提供密码,因为它使用的是HTTPS。您需要为ea分配一个API密钥
    GET users/fred/pets - returns all pets for user fred
    GET users/fred/pets/sparky - returns details on freds pet sparky
    
    GET http://tenant1.app.co/pets
    GET http://tenant2.app.co/pets
    GET http://tenant3.app.co/pets
    
    GET http://tenant1.app.co/pets/200
    GET http://tenant2.app.co/pets/201
    GET http://tenant3.app.co/pets/202