传统Web应用程序和API中的身份validation,授权和会话pipe理
如果我错了,请纠正我:在传统的Web应用程序中,浏览器会自动将会话信息附加到对服务器的请求中,以便服务器知道请求来自谁。 实际上究竟追加了什么?
但是,在基于API的应用程序中,这些信息不会自动发送,所以在开发API时,我必须检查自己,例如请求是否来自经过身份validation的用户? 这通常如何完成?
HTTP协议在devise上是无状态的,每个请求都是单独完成的,并在单独的上下文中执行。
会话pipe理背后的想法是将来自同一客户端的请求放在同一个上下文中。 这是通过由服务器发送一个标识符并将其发送给客户端完成的,然后客户端会保存这个标识符,并将其重新发送到后续的请求中,以便服务器识别它。
cookies
在典型的浏览器 – 服务器的情况下, 浏览器pipe理每个域的键/值对列表(称为cookie):
- Cookie可以由服务器(创build/修改/删除)使用
Set-Cookie
HTTP响应标头进行pipe理。 - Cookie可以通过parsing
Cookie
HTTP请求头来访问服务器(读取)。
面向Web的编程语言/框架提供了更高级别处理cookie的function,例如,PHP提供了setcookie
/ $_COOKIE
来写入/读取cookie。
会议
返回会话,在典型的浏览器 – 服务器案例(再次)中,服务器端会话pipe理利用客户端cookiepipe理。 PHP的会话pipe理设置会话ID cookie,并用它来标识后续的请求。
Web应用程序API?
现在回到你的问题。 因为您将负责deviseAPI并将其logging下来,因此实施将是您的决定。 你基本上必须
- 通过响应正文(XML / JSON auth响应)中的
Set-Cookie
HTTP响应头给客户端一个标识符。 - 有一个维护标识符/客户端关联的机制。 例如将标识符
00112233445566778899aabbccddeeff
与客户端/用户#1337
相关联的数据库表。 - 让客户重新发送在(1)处发送给它的所有后续请求中的标识符,可以在HTTP
Cookie
请求头中使用?sid=00112233445566778899aabbccddeeff
param(*)。 - 查找收到的标识符,使用(2)中的机制,检查是否有效的authentication,并被授权进行请求的操作,然后代表授权用户继续操作。
当然,你可以build立在现有的基础设施上,你可以在你的应用中使用PHP的会话pipe理(这将涉及1./2和4的authentication部分),并要求客户端实现做cookiepipe理会照顾到3.),然后你就可以完成你的应用逻辑的其余部分。
(*)每种方法都有缺点和优点,例如,使用GET请求参数更容易实现,但可能会有安全隐患,因为GET请求被logging。 您应该对关键(所有?)应用程序使用https。
会话pipe理是服务器的责任。 创build会话时,将生成会话令牌并将其发送到客户端(并存储在cookie中)。 之后,在客户端和服务器之间的下一个请求中,客户端(通常)将该令牌作为HTTP cookie发送。 所有会话数据都存储在服务器上,客户端只存储令牌。 例如,要在PHP中启动会话,只需要:
session_start(); // Will create a cookie named PHPSESSID with the session token
会话创build后,您可以保存数据。 例如,如果你想保持一个用户login:
// If username and password match, you can just save the user id on the session $_SESSION['userID'] = 123;
现在你可以检查一个用户是否被authentication了:
if ($_SESSION['userID']) echo 'user is authenticated'; else echo 'user isn't authenticated';
如果你愿意,你可以创build一个只有经过validation的用户的会话:
if (verifyAccountInformation($user,$pass)){ // Check user credentials // Will create a cookie named PHPSESSID with the session token session_start(); $_SESSION['userID'] = 123; }
对于Web应用程序和API,可靠的用户有很多种方法。 有几个标准,或者你可以写你自己的自定义授权/和或authentication。 我想指出授权和authentication之间的区别。 首先,应用程序需要authentication来自请求的用户(或api客户端)。 一旦用户已经被authentication,根据用户的身份应用需求确定任何authentication的用户有权执行某个应用(授权)。 对于大多数传统的Web应用程序来说,安全模型中没有细粒度的,所以一旦用户通过validation,在大多数情况下也是被授权执行某些操作的。 但是,这两个概念(authentication和授权)应该是两个不同的逻辑操作。
更进一步的,在传统的Web应用中,用户通过authentication和授权后(主要通过在数据库中查找用户名/密码对),授权和身份信息被写入会话存储中。 会话存储不必是服务器端,因为大部分的答案都表明,它也可以存储在客户端的cookie中,在大多数情况下是encryption的。 举个例子,PHP CodeIgniter框架默认是这样做的。 在客户端保护会话的机制有很多,我没有看到这种存储会话数据的方式比存储sessionId更安全,然后在服务器端的会话存储中查找。 另外,存储会话客户端在分布式环境中是非常方便的,因为它消除了在服务器端用于中央会话pipe理的devise解决scheme(或者使用已有的解决scheme)的需要。
此外,使用简单的用户密码对进行身份validation并不一定要通过在数据库中查找匹配用户logging的自定义代码完成。 例如有基本authentication协议或摘要authentication 。 在Windows平台这样的专有软件上,还有一些authentication用户槽的方法,例如ActiveDirectory
提供用户名/密码对不仅是validation方式,如果使用HTTPS协议,还可以考虑使用数字证书进行validation 。
在具体的使用案例中,如果devise使用SOAP作为协议的Web服务,还有SOAP协议的WS-Security扩展。
所有这些说,我会说下面的问题的答案进入WebApi授权/authentication机制select的决定程序:
1)什么是目标受众,是公开的,还是仅限于注册(付费)成员?
2)是运行还是* NIX或MS平台
3)预计有多less用户
4)多less敏感数据API处理(更强大的vs弱的身份validation机制)
5)是否有任何可以使用的SSO服务?
.. 还有很多。
希望这可以清除一些东西,因为方程中有很多variables。
如果基于API的APP是客户端,那么API必须有选项来从服务器响应stream中检索/读取cookie并存储它。 在为相同服务器/url准备请求对象时自动添加Cookie。 如果不可用,则无法检索会话ID。
我build议你发送一些令牌与每个请求。
根据服务器和服务,这些可以是GET / POST请求中的JSESSIONID参数,也可以是Web Service请求中SOAP over HTTP中成熟的SAML 。
你是对的,那么在标准环境中“自动”的原因是因为cookie比URL传播更受欢迎,以便为用户保持漂亮。 也就是说,浏览器(客户端软件)pipe理存储和发送会话cookie以及每个请求。
在API世界中,简单的系统通常只有身份validation证书随每个请求一起传递(至less在我的工作中)。 客户端作者通常(以我的经验)不愿意实现cookie存储,并传输每一个请求,通常任何超过最低限度…
对于基于HTTP的API,还有很多其他的authentication机制,HTTP基本/摘要来命名一对,当然,如果我没有弄错的话,这个authentication机制是专门为这些东西而devise的。 没有cookies维护,证书是每一个交换的一部分(相当肯定)。
另一个需要考虑的就是你要在API中的服务器上进行会话。 网站上的会话为当前用户提供存储空间,通常存储less量的数据以从页面到页面从数据库中取出数据。 在API的背景下,这种需求越来越less,因为事情或多或less都是无状态的,一般来说当然是这样。 这真的取决于服务在做什么。