2013-02-17 69 views
6

我已经为CakePHP应用程序构建了一个简单的测试API,它将允许用户从移动设备(或任何设备)登录并获得JSON响应。此API可用于PhoneGap中构建的移动应用程序。使用Sessions和令牌进行API身份验证

的登录方法看起来像这样:

public function login() 
{ 
    if($this->request->is('post')) 
    { 
     // Use custom method in Model to find record with password params 
     $findUser = $this->User->findUser(
      $_POST['username_or_email'], 
      AuthComponent::password($_POST['password']) 
     ); 

     // If a user exists and matches params 
     if($findUser) 
     {       
      $this->User->id = $findUser['User']['id']; 

      $this->autoRender = false; 
      $this->response->type('json'); 
      $this->response->body(json_encode(array('authenticated'=>true,'message'=>__('You have been logged in successfully')))); 
     } 
     else 
     { 
      $this->autoRender = false; 
      $this->response->type('json'); 
      $this->response->body(json_encode(array('authenticated'=>false,'message'=>__('Username or password is incorrect')))); 
     } 

    } 
    else 
    { 
     $this->autoRender = false; 
     $this->response->type('json'); 
     $this->response->body(json_encode(array('message'=>'GET request not allowed!'))); 
    } 
} 

的移动设备(或API的用户)可以发送自己的登录信息,然后他们得到的JSON请求为真或假的认证。 这个布尔值不是用来给用户的访问权限,而是告诉移动应用程序他们是否可以看到某些屏幕,并且他们只有获得数据或者如果会话存在就可以发送数据!

就像刚才陈述的那样,它们实际上也是在设备上登录到API本身,所以如果他们直接访问网站(来自该设备),他们将会有一个会话并看到相同的JSON响应。

因此,基本上用户在与服务器通信的设备上的会话持续时间内保持登录状态。这与需要为每个请求传递的令牌不同,因为在此示例中它们具有会话。

现在的问题...

  1. 是它的做法对于用户是坏“实际上”登录到API 与会话如上所示?它似乎是处理设备身份验证的最安全方式,因为它使用与直接Web根相同的逻辑。

  2. 我已经看到了一些API使用的访问令牌,而不是这我也 实现(用户得到他们的令牌,而不是返回布尔 并没有创建会话)。但从我可以告诉,这似乎 喜欢更多的工作,然后我需要检查访问令牌对 用户每次请求时记录。

+0

这是CakePHP的一个很好的REST API插件。也许你可以从https https://github获得一些指针。com/kvz/cakephp-rest-plugin(它使用令牌与Auth组件结合使用) – 2013-02-21 13:10:07

+0

是的,我以前见过,但我一直在寻找自己开发的东西。但他们也使用'$ this-> Auth-> login()',它实际上将用户登录到系统并创建一个会话。 – Cameron 2013-02-21 16:12:19

+0

是的。我正在使用它,但是覆盖了beforeFilter中的一些功能,以不同的方式使用不同的令牌进行授权,同时仍然保留了插件和CakePHP给我的一些automagick。 – 2013-02-21 18:32:28

回答

2

Restful API限制使用会话并保存系统状态。每个请求都必须登录用户。 访问tokes是伟大的,但也需要额外的处理。
最简单的方式是通过HTTP基本认证(“授权” HTTP标头)发送授权数据
http://www.httpwatch.com/httpgallery/authentication/
移动应用程序可以很容易地做到这一点,很容易添加此头为每个请求API。
在服务器端:

$username = env('PHP_AUTH_USER'); 
$password = env('PHP_AUTH_PW'); 

而且过程与此数据用户登录在ApiAppController-> beforeFilter()

+0

不确定您的意思是“限制”,因为我可以处理所有请求,并在移动设备存在会话后正常发送数据。因此,如果用户已经登录,他们现在将拥有一个会话,并且能够像预期的那样访问整个API中的方法,而无需对每个请求进行身份验证。所以没有看到使用基本身份验证和访问令牌的优点,除非我错了? – Cameron 2013-02-20 17:47:57

+0

当然,在API或其他地方使用会话没有PHP限制。但根据广泛传播的API建议称为“Restful API” - API必须是无状态的,这意味着它不会在任何2个请求之间存储任何内容。这里是关于它的问题 - http://stackoverflow.com/questions/8711044/is-it-good-to-implement-rest-api-using-sessions – Swayok 2013-02-20 20:58:04

+0

这里是关于REST - http://en.wikipedia。组织/维基/ Representational_state_transfer。我建议你坚持这个建议 – Swayok 2013-02-20 21:01:09

3

让您的应用登录每次,而与登录通对作为Swayok最后建议。当您登录时,服务器会生成一个令牌并将其返回给客户端。客户端在发出请求时会使用此令牌。在每个请求上,服务器检查令牌是否有效,如果是,则执行请求。

这与会话的工作方式非常相似,服务器端框架在内部对其进行管理,并且这些令牌会不时过期。然而,正如Swayok正确指出的那样,您不希望会话主要是因为您是RESTful API应该没有状态。您可以获得相同的实用程序,无需存储关于用户的任何用户特定数据,也不会在每次请求时记录用户。

下面是关于这个good article,或者你可以尝试Facebook的图形API资源管理器,看看它在行动

+1

注 - 使用令牌时,您需要通过GET或POST将它们添加到每个请求中,并添加对每个请求进行一些附加编程。通过使用基本身份验证标头 - 您只需要制作一种方法为任何请求添加标头,并使用该方法与服务器进行通信(即使用户尚未登录,也可以使用该方法)。实际上你可以通过Basic Auth header =)以用户登录的形式传递一个令牌,有时你不需要一个可以过期的令牌=)什么样的方式可以选择 - 取决于你和你的应用程序的需求=) – Swayok 2013-02-26 12:26:25

23

编辑
为了清楚起见,我不是REST的支持者,我是一个支持RESTful/REST的服务。如果你看看互联网上的所有API,很少有人真正坚持一种标准。无论您选择什么方案都取决于您的具体问题空间。只是尽量是安全的,使用直观的设计选择(即不名称的服务“猫”,如果它返回有关“狗”的信息)
末编辑

它是基于REST API的很好的做法来管理一些会话/标记方案的形式。真正的理想(至少在我看来,这个问题上有许多学派)设置涉及滚动令牌。

如果您完全担心您的API的安全性,那么应该将权限管理出您的数据库层。是的,这会造成一个瓶颈,但这实际上是一件好事。每次需要击中数据库来验证客户端令牌时,都会在整个过程中增加额外的步骤。这会降低API,这在安全的系统中实际上是需要的。你不希望恶意个人能够每秒击中你的API 3000次,你希望他们的请求挂起一段(有点)相当大的一小部分时间。

这与MD5散列算法类似。他们中的许多人重新计算了几百次哈希,并在两者之间进行了随机暂停。这有助于防止恶意客户端试图暴力破解密码(通过对密码字符串的每个变体进行测试需要更多时间)。这同样适用于您的API。

另一个好处是,如果你的DO有一个反复尝试登录的恶意用户,如果你是从数据库层管理他们,那么你可以用红旗标出他们的IP地址/用户名/什么 - 具备-你,只是在步骤放弃他们的请求1.

无论如何,对于一个建议的过程(与滚动令牌,你可以切出的这部分如果它似乎矫枉过正,但是这是海拉安全):

  1. 用户点击'登录'服务,这需要用户名/密码,并返回两个令牌,一个私人访问令牌和一个公共请求t令牌(服务器将这些令牌存储在数据库中)。
  2. 客户端存储在一个安全的地方,这些令牌
  3. 用户访问另一个端点推/拉一些数据
    • 请求包括时间戳
    • 请求中包含公共请求令牌
    • 请求中,包含一个访问令牌=>该令牌应该是由时间戳字符串连接到私有访问令牌字符串结尾的字符串的MD5哈希
  4. 服务器将P ublic请求令牌,使用它来查找已存储
    • 的服务器采用的私人访问令牌,并在时刻字符串会连接,然后又把这个字符串的MD5
    • 私人访问令牌如果新的访问令牌匹配客户端发送服务器HURRAY的客户端,这个客户端被验证,所以推/拉数据
  5. (可选)服务器为每个请求生成新的令牌,并将它们返回给客户端。这样每个事务都会使旧的令牌无效,如果发生某种中间人攻击,如果VALID用户已经完成了他们的请求,那么恶意用户现在拥有无效的令牌,并且不能开始搞乱你的API。该方案试图确保恶意用户不会期望拦截服务器和客户端之间的单一通信,并且仍然可以访问系统。如果他们这样做,那么REAL用户应该立即获得无效的令牌。然后应该触发他们的API客户端重新登录'登录'服务,获得新的有效令牌。这再次将恶意用户踢出系统。

该方案不是100%安全的,不会有用户访问系统。通过在令牌上添加过期日期可以使其更安全。此方案还具有额外的好处,即您可以为用户/令牌分配特定的权限(即只读访问,只能看到某些终端点等)

这不是您唯一可以做事情的方式,我想查找其他的身份验证方案,并采取你想要什么,从他们每个人(OAUTH是一个良好的开端,那么我想看看Facebook的/ Twitter的/ Instagram的)

+0

你的过程这里解释称为HMAC。为进一步阅读http://en.wikipedia.org/wiki/Hash-based_message_authentication_code – 2015-04-16 17:21:52

0

回答您的问题

  1. 只要您在应用程序关闭时关闭会话并在需要时重新创建会话,这不是一个坏习惯。它们就像他们在浏览器中登录他们所知道的一样,并且具有登出的功能,但是应用程序上也应该有相同的功能,否则他们可能会关闭应用程序,但实际上并未结束会话。您可以通过多种方式处理此问题,方法是让他们在关闭应用程序时注销自动检查
  2. 令牌是进行上述操作的增强方式,但您必须考虑令牌在传输时的安全程度,服务器需要验证令牌对每个请求。你已经说过,看起来更多的工作是如此,如果你有更多的工作,并且如果你有时间或金钱的限制,并寻找答案,说会话风格是否会在将来危害你的应用程序,只要你控制会话并且不会结束会话而离开用户。如果你有时间,然后实现令牌,你会喜欢它。
相关问题