简体   繁体   English

php中基于令牌的身份验证

[英]token based authentication in php

I have an REST service on my webserver, written in php. 我的网络服务器上有一个REST服务,用php编写。 I was wondering, what would be the best authentication (besides basic http access authentication). 我想知道,什么是最好的身份验证(除了基本的http访问身份验证)。 I've heared of token-based auth, and would like to ask if someone could explain the main steps. 我听说过基于令牌的身份证,并且想问一下是否有人可以解释主要步骤。

  • On a GET: Is the token send visible? 在GET上:令牌发送是否可见? (isn't that unsafe?) (那不安全吗?)
  • How do I make the token only valid for a specific time? 如何使令牌仅在特定时间有效?
  • ... ...

Client: Android/Browser; 客户端:Android /浏览器; Server: Apache, PHP5 服务器:Apache,PHP5

It can be done either way, and values in a GET request aren't really any more visible than values in a POST request. 它可以以任何一种方式完成,并且GET请求中的值实际上不比POST请求中的值更明显。 If anybody can "see" (ie intercept ) the request, he can see everything you're sending. 如果有人可以“看到”(即拦截 )请求,他可以看到你发送的所有内容。 In the end an HTTP request is just a bunch of HTTP headers possibly followed by a body. 最后,HTTP请求只是一堆HTTP头,可能后跟一个正文。 The URL is send in the first GET /foo/bar HTTP/1.1 line, other values are just send in different, following lines. URL在第一个GET /foo/bar HTTP/1.1行发送,其他值只是在不同的行中发送。

So it's up to you where you expect your authentication token to be send. 因此,您可以在何处发送您的身份验证令牌。 You can require it to be a query parameter that is appended to every request: 您可以要求它是附加到每个请求的查询参数:

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

To really use the HTTP protocol as intended though, you should use the Authorization HTTP header: 要真正按照预期使用HTTP协议,您应该使用Authorization HTTP标头:

Authorization: MyScheme 123456:abcde...

The content of this header is entirely up to you. 此标题的内容完全取决于您。 It usually specifies an authorization method like Basic , followed by whatever you want to require for authentication. 它通常指定一个像Basic这样的授权方法,然后是您想要进行身份验证的任何方法。 This can simply be the username and password, a hash of them, an opaque token the client has obtained at some point or anything else really. 这可以简单地是用户名和密码,它们的哈希值,客户端在某些时候或其他任何地方获得的不透明令牌。

I'd recommend a token system or a request signing system, with the latter being very much preferred. 我建议使用令牌系统或请求签名系统,后者非常受欢迎。 In a request signing system, the client has to obtain a token from you. 在请求签名系统中,客户端必须从您那里获取令牌。 It then sends a hash of this token and certain characteristics of the request to authenticate the request, eg sha1(Token + Timestamp + Request URL + Request Body) . 然后,它发送此令牌的散列和请求的某些特征以验证请求,例如sha1(Token + Timestamp + Request URL + Request Body) Your server can validate this without the client having to send the token in plain text on each request. 您的服务器可以验证这一点,而客户端不必在每个请求上以纯文本形式发送令牌。

How do I make the token only valid for a specific time? 如何使令牌仅在特定时间有效?

You save the token server-side with an expiration timestamp and check against it. 您使用到期时间戳保存令牌服务器端并检查它。

Here's a question about token-based authentication. 这里有一个问题,关于基于令牌的认证。 I think the most common token-based authentication today is OAuth . 我认为今天最常见的基于令牌的身份验证是OAuth But to answer your questions: 但要回答你的问题:

On a GET: Is the token send visible? 在GET上:令牌发送是否可见? (isn't that unsafe?) (那不安全吗?)

You can pass your tokens through HTTP headers so they are not so easily seen. 您可以通过HTTP标头传递令牌,这样就不会那么容易看到它们。 OAuth allows this . OAuth 允许这样做 Note that the tokens are still visible, they're just not in the GET query parameters. 请注意,令牌仍然可见,它们不在GET查询参数中。

How do I make the token only valid for a specific time? 如何使令牌仅在特定时间有效?

Since you control (create) the tokens, you can set expiry dates for each token. 由于您控制(创建)令牌,因此您可以为每个令牌设置到期日期。 On every request of your API, you should just check your token storage (eg Database) if the given token is still valid. 在API的每个请求中,如果给定令牌仍然有效,您应该检查您的令牌存储(例如数据库)。 If it is not, then you can abort the request (maybe return a HTTP 401 error). 如果不是,那么您可以中止请求(可能返回HTTP 401错误)。

You can use fire-base php JWT (JSON Web Token) for token based authentication. 您可以使用基于Firefox的JWT(JSON Web令牌)进行基于令牌的身份验证。

1)Install php jwt by running composer command composer require firebase/php-jwt 1)通过运行composer命令composer require firebase / php-jwt来安装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')

After that Generate your token 之后生成您的令牌

$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];

provide this token to your user " $jwt " . 将此令牌提供给您的用户“ $ jwt ”。 On each request user need to send token value with each request to validate user. 在每个请求中,用户需要使用每个请求发送令牌值以验证用户。

 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 您可以逐步完成基于php令牌的身份验证的完整配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM