使用会话与令牌进行 API 身份验证 [英] Using Sessions vs Tokens for API authentication

查看:30
本文介绍了使用会话与令牌进行 API 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 CakePHP 应用程序构建了一个简单的测试 API,它可以让用户从移动设备(或任何与此相关的设备)登录并获得 JSON 响应.此 API 可用于内置于 PhoneGap 的移动应用.

I have built a simple test API for a CakePHP application that will let a user login from a mobile device (or any device for that matter) and get a JSON response. This API could be used for a mobile app built in PhoneGap.

登录方法如下所示:

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 作为真或假进行身份验证.此布尔值不用于授予用户访问权限,而是告诉移动应用他们是否可以看到某些屏幕,并且他们只能获取数据或在会话存在时可以发送数据!

The mobile device (or any API user) can send their login details and then they get the request as JSON as true or false for authenticated. This boolean is NOT used to give the user access, it instead tells the mobile app if they can see certain screens and they ONLY get the data or can send data if the session exists!

如前所述,他们实际上也在设备上登录了 API 本身,因此如果他们直接(从该设备)访问网站,他们将进行会话并看到相同的 JSON 响应.

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

So essentially a user remains logged in for the duration of the session on the device they communicated with the server on. This is different to a token which would need to be passed for every request, where as in this example they have a session.

现在问题...

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

  1. Is it bad practice for the user to be 'actually' logged into the API with a session like shown above? It seems like the most secure way to handle authentication for a device as it's using the same logic as the direct web root.

我已经看到一些 API 使用访问令牌来代替,我也看到过已实现(用户返回他们的令牌而不是布尔值并且没有创建会话).但据我所知,这似乎喜欢更多的工作,然后我需要检查访问令牌每次发出请求时的用户记录.

I've seen some APIs use access tokens instead which I've also implemented (user gets their token returned instead of the boolean and no session is created). But from what I can tell, this seems like more work as then I need to check for the access token against a user record every time a request is made.

推荐答案

编辑
为了清楚起见,我不是 REST 的支持者,我是 RESTful/RESTlike 服务的支持者.如果您查看 Internet 上的所有 API,实际上很少有人遵循一个标准.您选择的任何方案将取决于您的特定问题空间.尽量确保安全并使用直观的设计选择(即,如果服务返回有关狗"的信息,请不要将其命名为猫")
结束编辑

在 RESTful API 中管理某种形式的会话/标记化方案是一种很好的做法.真正理想的(至少在我看来,有很多关于这个问题的思想流派)设置涉及滚动令牌.

It is good practice in RESTful API's to manage some form of session/tokenizing scheme. Really the ideal (at least in my opinion, there are many schools of thought on this problem) setup involves rolling tokens.

如果您完全关心 API 的安全性,则应在数据库层之外管理权限.是的,这会造成瓶颈,但这实际上是一件好事.每次都需要访问数据库来验证客户端的令牌,这在整个过程中增加了一个额外的步骤.这会减慢 API,这在安全系统中实际上是可取的.您不希望恶意个人每秒能够访问您的 API 3000 次,您希望他们的请求挂起(有点)相当大的几分之一秒.

If you are at all concerned with the security of your API, then permissions should be managed out of your database layer. Yes, this creates a bottleneck, BUT THAT IS ACTUALLY A GOOD THING. Needing to hit the database every single time to validate a client's token adds an extra step in the entire process. This slows down the API, which is actually desireable in a secure system. You don't want a malicious individual to be able to hit your API 3000 times a second, you want their requests to hang for a (somewhat) sizeable fraction of a second.

这类似于 MD5 哈希算法.他们中的许多人重新计算散列数百次,中间有随机暂停.这有助于防止恶意客户端尝试暴力破解密码(通过花费更多时间来测试密码字符串的每个变体).这同样适用于您的 API.

This is similar to MD5 hashing algorithms. Many of them recalculate the hash a few hundred times, with random pauses in between. This helps to keep a malicious client from attempting to brute force a password (by making it take more time to test each variation of the password string). The same applies to your API.

另一个好处是,如果您确实有一个恶意用户试图一遍又一遍地登录,如果您从数据库层管理他们,那么您可以红色标记他们的 IP 地址/username/what-have-you 并在步骤 1 中删除他们的请求.

The other benefit, is that if you DO have a malicious user trying to log in over and over again, if you are managing them from the database layer, then you can red flag their IP Address/username/what-have-you and just drop their requests at step 1.

无论如何,对于建议的流程(使用滚动令牌,如果它看起来有点矫枉过正,您可以删除其中的一部分,但这是非常安全的):

Anyway, for a suggested process (with rolling tokens, you can cut out parts of this if it seems overkill, but this is hella secure):

  1. 用户点击登录"服务,这需要用户名/密码,并返回两个令牌,一个私有访问令牌和一个公共请求令牌(服务器将这些令牌存储在数据库中).
  2. 客户端将这些令牌存储在安全的地方
  3. 用户访问另一个端点以推/拉一些数据
    • 请求包含时间戳
    • 请求包括公共请求令牌
    • 请求包含访问令牌=>此令牌应该是字符串的 MD5 哈希值,该字符串是将时间戳字符串连接到私有访问令牌字符串的末尾所产生的
  • 服务器获取该私有访问令牌,并连接时间戳字符串,然后获取该字符串的 MD5
  • 如果新的访问令牌与客户端发送给服务器的访问令牌匹配,HURRAY,则验证此客户端,因此推/拉数据

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

This scheme is not 100% secure, no user access system ever will be. It can be made more secure by adding expiration dates on tokens. This scheme also has the added benefit that you can assign specific permissions to users/tokens (ie Read-Only access, only certain End-Points can be seen, etc)

这不是您做事的唯一方法,我会查找其他身份验证方案并从中获取您想要的东西(OAUTH 是一个很好的起点,然后我会看看 Facebook/Twitter/Instagram)

This is not the only way you can do things, I would look up other Authentication Schemes and take what you want from each of them (OAUTH is a good place to start, then I'd look at Facebook/Twitter/Instagram)

这篇关于使用会话与令牌进行 API 身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆