【问题标题】:token based authentication in phpphp中基于令牌的身份验证
【发布时间】:2012-03-19 14:56:33
【问题描述】:

我的网络服务器上有一个 REST 服务,用 php 编写。我想知道,最好的身份验证是什么(除了基本的 http 访问身份验证)。 我听说过基于令牌的身份验证,想问一下是否有人可以解释主要步骤。

  • 在 GET 上:发送的令牌是否可见? (这不是不安全吗?)
  • 如何使令牌仅在特定时间有效?
  • ...

客户端:Android/浏览器;服务器:Apache、PHP5

【问题讨论】:

  • 通过 POST 方法将其设为隐藏字段
  • 如果我只能使用 POST,RESTfull 服务的意义是什么;) 我已经实现了 PUT、POST、GET、DELETE,当然每种 http 方法都有不同的功能
  • 隐藏令牌的可见性
  • GET domain/user/2 为我提供有关用户的信息,POST domain/user/2 创建一个用户。 - GET 和 POST 之间有很大的不同。这就是 REST 的意义所在:en.wikipedia.org/wiki/Representational_state_transfer

标签: php authentication rest


【解决方案1】:

这两种方法都可以,GET 请求中的值实际上并不比 POST 请求中的值更可见。如果有人可以“看到”(即拦截)请求,他就可以看到您发送的所有内容。最后,一个 HTTP 请求只是一堆 HTTP 标头,可能后跟一个正文。 URL 在第一行 GET /foo/bar HTTP/1.1 发送,其他值只是在不同的行中发送。

因此,您希望将身份验证令牌发送到哪里取决于您。您可以要求它是附加到每个请求的查询参数:

GET /foo/bar?user=123456&token=abcde...

要真正按预期使用 HTTP 协议,您应该使用 Authorization HTTP 标头:

Authorization: MyScheme 123456:abcde...

此标头的内容完全由您决定。它通常指定像Basic 这样的授权方法,然后是您想要进行身份验证的任何内容。这可以只是用户名和密码、它们的哈希值、客户端在某个时候获得的不透明令牌或其他任何东西。

我推荐一个令牌系统或一个请求签名系统,后者是非常受欢迎的。在请求签名系统中,客户端必须从您那里获取令牌。然后它发送这个令牌的哈希和请求的某些特征来验证请求,例如。 sha1(Token + Timestamp + Request URL + Request Body)。您的服务器可以验证这一点,而客户端不必在每个请求中以纯文本形式发送令牌。

如何使令牌仅在特定时间有效?

您使用过期时间戳保存令牌服务器端并检查它。

【讨论】:

  • 谢谢,我想我现在有了基本的想法。还有几个问题: 1. 当客户端获得令牌时 - 这将是一个“简单的 json 文件”,例如,包含“TOKEN_A”? 2.如果客户端只发送一个哈希,包括时间戳,我如何在服务器端检查哈希是否有效?遍历 las X ms 的可能散列?
  • 1.是的,无论哪种方式最适合您的模型。也许用户需要在网站上注册并从那里复制和粘贴令牌。也许您也可以通过 API 来执行此操作,在这种情况下,JSON 响应就可以了。 2.Authorization header 需要包含用户id和token hash。请求还必须包含时间戳,例如在 Date 标头中,这是非常标准的。哈希将基于该文字 Date 标头。您的服务器只是为用户查找令牌,确保日期在当前时间的±几分钟内并重新创建相同的哈希。
  • 所以基本的想法是:我不是发送纯令牌,而是向您发送哈希和信息 A、B、C。服务器从 UID 中获取令牌,并使用信息 A、B、C 对其进行哈希处理。并检查哈希是否相同?! - (+时间验证人员)- 这很聪明 :D 非常感谢
  • @Spring 更灵活。每个客户都可以获得一个唯一的令牌,如果需要,可以单独撤销这些令牌。它也完全不需要客户端存储敏感信息,只需要一个无意义的令牌,随时可能失效。
  • @Spring Token 是共享密钥。任何人都不能重新创建哈希,除非该人知道共享秘密。有人可能能够重用同一个令牌来重复同一个请求,这是真的。如果这看起来像是可疑活动,服务器可以过滤此类相同的请求。散列中使用的日期需要作为 HTTP Date 标头(或类似标头)发送。 SSL 确实充分利用了这种多余的安全性,但更多的安全性也不是坏事,尤其是当它只是一种简单而有效的散列算法时。
【解决方案2】:

这是关于基于令牌的身份验证的question。我认为当今最常见的基于令牌的身份验证是OAuth。但要回答您的问题:

在 GET 上:发送的令牌是否可见? (这不是不安全吗?)

您可以通过 HTTP 标头传递您的令牌,这样它们就不会那么容易被看到。 OAuthallows this。请注意,令牌仍然可见,只是不在 GET 查询参数中。

如何使令牌仅在特定时间有效?

由于您控制(创建)令牌,您可以为每个令牌设置到期日期。对于 API 的每个请求,如果给定的令牌仍然有效,您应该只检查您的令牌存储(例如数据库)。如果不是,那么您可以中止请求(可能返回 HTTP 401 错误)。

【讨论】:

  • 谢谢,我会看看 OAuth。我想我现在有了基本的想法:)
  • POST 和 GET 都是不安全的。为了确保它们的安全,您需要在顶层添加另一个加密层,例如 SSL。
【解决方案3】:

您可以使用 fire-base php JWT (JSON Web Token) 进行基于令牌的身份验证。

1)通过运行composer命令安装php jwt composer require firebase/php-jwt

   require_once('vendor/autoload.php');
   use \Firebase\JWT\JWT; 
   define('SECRET_KEY','Your-Secret-Key')  // secret key can be a random string  and keep in secret from anyone
   define('ALGORITHM','HS512')

然后生成你的令牌

$tokenId    = base64_encode(mcrypt_create_iv(32));
                $issuedAt   = time();
                $notBefore  = $issuedAt + 10;  //Adding 10 seconds
                $expire     = $notBefore + 7200; // Adding 60 seconds
                $serverName = 'http://localhost/php-json/'; /// set your domain name 


                /*
                 * Create the token as an array
                 */
                $data = [
                    'iat'  => $issuedAt,         // Issued at: time when the token was generated
                    'jti'  => $tokenId,          // Json Token Id: an unique identifier for the token
                    'iss'  => $serverName,       // Issuer
                    'nbf'  => $notBefore,        // Not before
                    'exp'  => $expire,           // Expire
                    'data' => [                  // Data related to the logged user you can set your required data
                'id'   => "set your current logged user-id", // id from the users table
                 'name' => "logged user name", //  name
                              ]
                ];
              $secretKey = base64_decode(SECRET_KEY);
              /// Here we will transform this array into JWT:
              $jwt = JWT::encode(
                        $data, //Data to be encoded in the JWT
                        $secretKey, // The signing key
                         ALGORITHM 
                       ); 
             $unencodedArray = ['jwt' => $jwt];

将此令牌提供给您的用户“$jwt”。在每个请求中,用户需要在每个请求中发送令牌值来验证用户。

 try {
           $secretKey = base64_decode(SECRET_KEY); 
           $DecodedDataArray = JWT::decode($_REQUEST['tokVal'], $secretKey, array(ALGORITHM));

           echo  "{'status' : 'success' ,'data':".json_encode($DecodedDataArray)." }";die();

           } catch (Exception $e) {
            echo "{'status' : 'fail' ,'msg':'Unauthorized'}";die();
           }

You can get step by step full configurations for php token based authentication

【讨论】:

    猜你喜欢
    • 2016-01-29
    • 2021-01-25
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 2013-02-11
    • 2010-12-24
    相关资源
    最近更新 更多