传统Web应用程序和API中的身份验证,授权和会话管理

Jie*_*eng 73 authentication api session authorization

如果我错了,请纠正我:在传统的Web应用程序中,浏览器会自动将会话信息附加到服务器的请求中,因此服务器可以知道请求来自谁.到底究竟附加了什么?

但是,在基于API的应用程序中,此信息不会自动发送,因此在开发API时,我必须检查自己,例如请求是否来自经过身份验证的用户?这通常是怎么做的?

aul*_*ron 120

HTTP协议在设计上是无状态的,每个请求都是单独完成的,并在单独的上下文中执行.

会话管理背后的想法是将来自同一客户端的请求放在同一个上下文中.这是通过服务器发出标识符并将其发送到客户端来完成的,然后客户端将保存此标识符并在后续请求中重新发送,以便服务器可以识别它.

饼干

在典型的浏览器 - 服务器案例中; 浏览器管理每个域的键/值对列表,称为cookie:

  • Cookie可以由服务器(创建/修改/删除)使用Set-CookieHTTP响应标头进行管理.
  • 服务器(读取)可以通过解析CookieHTTP请求标头来访问Cookie .

以Web为目标的编程语言/框架提供了在更高级别处理cookie的功能,例如,PHP提供setcookie/ $_COOKIE写入/读取cookie.

会议

回到会话,在典型的浏览器服务器情况下(再次),服务器端会话管理利用客户端cookie管理.PHP的会话管理设置会话ID cookie并使用它来识别后续请求.

Web应用程序API?

现在回到你的问题; 因为你是负责设计API并记录它的人,所以你的决定就是实施.你基本上必须这样做

  1. Set-Cookie在响应主体内部(XML/JSON身份验证响应)为客户端提供标识符,通过HTTP响应标头.
  2. 有一个维护标识符/客户端关联的机制.例如,将标识符00112233445566778899aabbccddeeff与客户端/用户#相关联的数据库表1337.
  3. 让客户端在所有后续请求中重新发送(1.)发送给它的标识符,无论是在HTTP Cookie请求头,?sid=00112233445566778899aabbccddeeffparam(*)中.
  4. 查找收到的标识符,使用(2.)处的机制,检查是否有效的身份验证,并被授权执行请求的操作,然后代表auth'd用户继续操作.

当然,您可以在现有基础架构的基础上构建,您可以在应用程序中使用PHP的会话管理(将负责1./2.以及4.的身份验证部分),并要求客户端实现进行cookie管理(将照顾3.),然后你完成其余的app逻辑.


(*)每种方法都有缺点和优点,例如,使用GET请求参数更容易实现,但可能有安全隐患,因为记录了GET请求.您应该将https用于关键(所有?)应用程序.

  • 完美答案!谢谢 (2认同)

Gui*_*tro 46

会话管理是服务器的责任.创建会话时,会生成会话令牌并将其发送到客户端(并存储在cookie中).之后,在客户端和服务器之间的下一个请求中,客户端将令牌(通常)作为HTTP cookie发送.所有会话数据都存储在服务器上,客户端只存储令牌.例如,要在PHP中启动会话,您只需:

session_start();  // Will create a cookie named PHPSESSID with the session token
Run Code Online (Sandbox Code Playgroud)

创建会话后,您可以在其上保存数据.例如,如果要保持用户记录:

// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;
Run Code Online (Sandbox Code Playgroud)

现在,您可以检查用户是否已通过身份验证:

if ($_SESSION['userID'])
    echo 'user is authenticated';
else
    echo 'user isn't authenticated';       
Run Code Online (Sandbox Code Playgroud)

如果需要,您只能为经过身份验证的用户创建会话:

if (verifyAccountInformation($user,$pass)){ // Check user credentials
    // Will create a cookie named PHPSESSID with the session token
    session_start();
    $_SESSION['userID'] = 123;
}
Run Code Online (Sandbox Code Playgroud)


tos*_*ske 9

对于Web应用程序和API,真实用户有很多种方法.有几种标准,或者您可以编写自己的自定义授权/和/或身份验证.我想指出授权和身份验证之间的区别.首先,应用程序需要验证请求来自的用户(或api客户端).一旦用户通过身份验证,基于用户的身份应用程序需要确定任何经过身份验证的用户有权执行某些应用程序(授权).对于大多数传统的Web应用程序,安全模型中没有精细的粒度,因此一旦用户通过身份验证,在大多数情况下,它也被授权执行某些操作.但是,这两个概念(身份验证和授权)应该是两个不同的逻辑操作.

此外,在经典Web应用程序中,在用户经过身份验证和授权后(主要通过在数据库中查找用户名/密码对),授权和身份信息被写入会话存储中.会话存储不必是服务器端,因为上面的大多数答案都表明,它也可以存储在客户端的cookie中,在大多数情况下是加密的.例如,PHP CodeIgniter框架默认执行此操作.在客户端有许多保护会话的机制,我没有看到这种存储会话数据的方式比存储sessionId更安全,然后在服务器端的会话存储中查找.此外,存储会话客户端在分布式环境中非常方便,因为它消除了在服务器端设计解决方案(或使用已有的解决方案)进行中央会话管理的需要.

此外,使用简单的用户密码对进行身份验证不一定非必须通过查找匹配数据库中的用户记录的自定义代码来完成.存在例如基本认证协议摘要认证.在Windows平台等专有软件上,还有一些验证用户槽的方法,例如ActiveDirectory

提供用户名/密码对不仅是验证方式,如果使用HTTPS协议,您还可以考虑使用数字证书进行身份验证.

在特定用例中,如果设计使用SOAP作为协议的Web服务,则还存在SOAP协议的WS-Security扩展.

有了所有这些,我想说下面问题的答案进入选择WebApi的授权/认证机制的决策程序:

1)目标受众是什么,是公开发布的,还是仅限注册(付费)成员?
2)是运行还是*NIX,或MS平台
3)预计会有多少用户
4)敏感数据API处理多少(更强大与更弱的身份验证机制)
5)是否有任何可以使用的SSO服务

.. 还有很多.

希望这可以解决问题,因为等式中有许多变量.