最后,在每个API中,我将从移动应用程序收到的请求发送到我网站代码库中的相应功能.然后相应的函数接受请求和请求参数,处理请求并返回所需的数据.然后,API以JSON格式将数据返回到移动应用程序.这是当前的工作流程.
现在,我想根据用户身份验证提供网站资源(即网站代码库和数据中的功能)的可用性.简而言之,我想在这种情况下实现“基于令牌的身份验证”方案.
以下应该是我实现’基于令牌的身份验证’之后的流程:
>当用户第一次通过在对登录API的请求中发送用户名和密码登录系统时,一旦成功验证该特定用户的用户名和密码组合,就会生成一个安全令牌.此安全令牌也将与用户名/密码/某些散列值一起存储到某些MySQL数据库表中,以识别用户进一步处理.如果验证失败,则不应生成安全令牌,用户也不应该登录.
>成功登录后,生成的安全令牌将在登录API成功响应时发送回用户.现在,直到用户使用每个后续请求登录,此令牌将被发送到相关API,并最终将其发送到身份验证功能以验证其有效性.
>如果任何请求发送了无效令牌,则应发送“请先登录”消息作为响应,并且网站资源不应该被访问.
>用户注销后,应从数据库中删除此安全令牌条目,或者应对其执行任何适当的操作.
从那以后,我在职业生涯中第一次开始“基于令牌的身份验证”,我的上述方法可能会出错.如果我做错了什么,请纠正我的错误.
我找到了以下链接,但那些我没有找到有用的链接,因为它们缺少一步一步描述的工作代码示例:
PHP HMAC Restful API that uses Phalcon Micro framework
如果您可以提供包含数据库表创建,PHP和MySQL之间的连接,然后创建安全令牌,检查当前登录用户的安全令牌的有效性等的整个代码,那对我来说真的很棒.
此外,如果您可以为上述两个(或两个)选项中的任何一个提供工作代码示例作为此问题的答案,这也将是非常好的.如果除了我提供的完整工作代码示例之外还有其他选项,欢迎您提出答案.
N.B.:-请不要建议我使用OAuth身份验证过程.
以下是我自己尝试的代码,但我不知道它是对还是错.我的方法是正确还是错误?
要创建令牌,我使用此函数作为参数,即用户的数据
define('SECRET_KEY',"fakesecretkey"); function createToken($data) { /* Create a part of token using secretKey and other stuff */ $tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // It can be 'stronger' of course /* Encoding token */ $token = hash('sha256',$tokenGeneric.$data); return array('token' => $token,'userData' => $data); }
因此,用户可以对自己进行身份验证并接收包含令牌(genericPart,他的数据,已编码)和未编码的数据的数组:
function auth($login,$password) { // we check user. For instance,it's ok,and we get his ID and his role. $userID = 1; $userRole = "admin"; // Concatenating data with TIME $data = time()."_".$userID."-".$userRole; $token = createToken($data); echo json_encode($token); }
然后用户可以将他的令牌发送给我未编码的数据,以便检查:
define('VALIDITY_TIME',3600); function checkToken($receivedToken,$receivedData) { /* Recreate the generic part of token using secretKey and other stuff */ $tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // We create a token which should match $token = hash('sha256',$tokenGeneric.$receivedData); // We check if token is ok ! if ($receivedToken != $token) { echo 'wrong Token !'; return false; } list($tokenDate,$userData) = explode("_",$receivedData); // here we compare tokenDate with current time using VALIDITY_TIME to check if the token is expired // if token expired we return false // otherwise it's ok and we return a new token return createToken(time()."#".$userData); } $check = checkToken($_GET['token'],$_GET['data']); if ($check !== false) echo json_encode(array("secureData" => "Oo")); // And we add the new token for the next request
我对吗?
解决方法
这是一张RFC 6750的图表
+--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| (Slim API) | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+
在苗条,你可以有三个端点:
POST用户名/密码:
/的OAuth / V1 /认证/
返回{token:foo}
GET,其中{token}是您的唯一令牌
/的OAuth / V1 /令牌/ {令牌}
返回{username:joe,permissions [‘page:admin’,’users:full’],expires:123456}
DELETE传递{token}
/的OAuth / V1 /令牌/撤消
回复200 OK和空身.
现在,它是如何工作的:
>当他们进行身份验证时,只需返回带有令牌的JSON对象,客户端将其存储在cookie之类的内容中.
>客户端将此文件传递到资源服务器中,如RFC section 2.1中所标识的那样(在数据库/ nosql / whatever中查找用户权限):
GET /resource HTTP/1.1
06001
您的资源服务器与后端的Slim API联系以确定您的权限.然后,服务器决定您可以看到的内容.
如果您不喜欢将其作为标题发送,请参阅section 2.2,它描述了如何在正文中发送它,或者section 2.3将其作为URI查询发送.
这些显然不需要是不同的服务器.你可以按照自己的意愿实现它.