简体   繁体   English

如何使用cURL通过HTTP标头发送和接收数据?

[英]How to send and receive data via HTTP header using cURL?

I am trying to build a simple API to allow a client to send me data over HTTPS. 我正在尝试构建一个简单的API,以允许客户端通过HTTPS向我发送数据。 I created a class that will take a username/password then it does a database look up. 我创建了一个将使用用户名/密码的类,然后进行数据库查找。 If the user is found then it issues a token. 如果找到用户,则它发出令牌。 Then the token will be send back to the requester via HTTP header. 然后,令牌将通过HTTP标头发送回请求者。

Once a username, password and a token sent back then the script reads the data sent from the client via $_POST request and processes it. 一旦发送回用户名,密码和令牌,脚本便会通过$_POST请求读取从客户端发送的数据并进行处理。

The challenge that I am having is sending the token to the requester via cURL and receiving the USERNAME , PASSWORD & TOKEN from the HTTP header correctly. 我面临的挑战是通过cURL将令牌发送给请求者,并正确地从HTTP标头接收USERNAMEPASSWORDTOKEN

My question is how can I correctly send the token via HTTP header in the generateToken() method? 我的问题是如何在generateToken()方法中通过HTTP标头正确发送令牌? Also how can I read the HTTP headers once the request is made? 发出请求后,如何读取HTTP标头?

Below is my class: api.php file 以下是我的课程:api.php文件

<?php
require('../classes/connection.php');

class api {

    private $user_name;
    private $user_password;
    private $user_token;
    private $db;
    private $keepAlive = 120; //2 minutes = 120 seconds
    private $authorizes = false;
    private $token = '';
    private $ch;
    private $user_ready = false;

    function api($database, $server){

        //establish a database connection
        $this->db = new connection($database, $server);
        $this->ch = curl_init();

        //read user_name, password, token from the header and set it
        if(isset($_SERVER['API-User-Name']))
            $this->user_name = $_SERVER['API-User-Name'];

        if(isset($_SERVER['API-User-Password']))
            $this->user_password = $_SERVER['API-User-Password'];

        if(isset($_SERVER['API-User-Token']))
            $this->user_token = $_SERVER['API-User-Token'];

        //check if the user is allowed
        if(  $this->authenticateAccess() === true  ){
            $this->authorizes = true;

            //ensure the token is valid otherwise generate a new token
            if(     $this->isValidToken()   )
                $this->user_ready = true;
            else 
                $this->generateToken();
        }
    }

    //return weather to process the send data
    public function isUserReady(){
        return $this->user_ready;
    }

    //return weather the user is authorized
    private function isAutherized(){
        return $this->authorizes;
    }

    //return the set token
    private function getToken(){
        return $this->token;
    }

    //check if the requester is authorized to access the system
    private function authenticateAccess(){

        //unauthorized old session
        $this->unautherizeExpiredTokens();

        if( $this->ch === false) 
            return false;

        if( empty($this->user_name)  || empty($this->user_password)  )
            return false;

        //ensure HTTPS is used  
        if( !isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') 
            return false;
         //read the user information                
         $get_user = $this->db->getDataSet('SELECT ip_addreses, user_password, token_expires_on, current_token
                                            FROM api_users
                                            WHERE user_name = ?
                                            LIMIT 1', array($this->user_name));

         if( count($get_user) != 1)
            return false;

         $data = $get_user[0];

         //remove bad values if any
         $ip_addreses = preg_replace("/[^0-9,.]/", "", $data['ip_addreses']);

         $allowed_ips = explode(',', $ip_addreses);

        //ensure the IP address is allowed
        if( !isset($_SERVER['REMOTE_ADDR']) || !in_array($_SERVER['REMOTE_ADDR'], $allowed_ips) )
            return false;

        //check if the password is valid    
        if( password_verify($this->password, $data['user_password'] ) )
            return true;
        else        
            return false;
    }


    //check if the token is valid
    private function isValidToken(){

        if(     !$this->isAutherized()  )
            return false;

        //unauthorized old session
        $this->unautherizeExpiredTokens();


        if( empty($this->user_token) )
            return false;

         $get_user = $this->db->getDataSet('SELECT token_expires_on, current_token
                                            FROM api_users
                                            WHERE user_name = ? AND current_token = ?
                                            LIMIT 1', array($this->user_name, $this->user_token ));

         if( count($get_user) != 1)
            return false;

        $data = $get_user[0];

        if( empty($data['token_expires_on']) || $data['current_token'] != $this->user_token )
            return false;

        //make sure that the token is not expired
        if( !empty($data['token_expires_on']) && time() > $data['token_expires_on'])
            return false;   

    }

    //generate a new token
    private function generateToken(){
            //generate a token          
            $token = md5(uniqid(mt_rand(), true));
            //set expiration date for this token
            $expire_on = time() + $this->keepAlive;

            //Save the new token in the database with expiration time = $this->keepAlive seconds
            $update = $this->db->processQuery('UPDATE api_users
                                               SET current_ip = ?,
                                               current_token = ?,
                                               token_expites_on = ?
                                               WHERE user_name = ?', array($_SERVER['REMOTE_ADDR'], $token, $expire_on ));
            //if the token is saved in the database then send the new token via cURL header.                                   
            if($update){
                //set the token as a header value and then sent it back to the requester.
                $this->token = $token;
                $curl_header = array();
                $curl_header[] = 'API-User-Token: ' . $token;
                curl_setopt($this->ch, CURLOPT_HEADER, true);
                curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_header);

                return $token;
            } else
                return false;   
    }


    //remove old tokens
    private function unautherizeExpiredTokens(){

        $this->db->processQuery('UPDATE api_users
                                 SET current_ip = NULL,
                                 current_token = NULL,
                                 token_expites_on = NULL
                                 WHERE token_expites_on IS NOT NULL AND token_expites_on <= ?', array( time() ) );  

    }

}

?>

And to use this class I would do the following form the API access link. 为了使用此类,我将执行以下形式的API访问链接。 Once I figure out how to ready the http data then there will be no need to pass the $username and $password to the class instead it will be ready in the class from the header. 一旦我弄清楚了如何准备http数据,就不需要将$username$password传递给该类,而是可以在标头中的类中准备好了。

Therefore, the access.php file will look like the following 因此,access.php文件将如下所示

include('api.php');


$request = new api('database_name','serverIPaddress');


if( $request->isUserReady() ){
    //process transaction all transactions
    $_POST['notes'];  //// take the data validated it and then insert into the database

    echo 'Bingo!';

} else {
    echo 'You are not authorized to use this API';
}

?>

To use this API the client will have to call it like so client.php file will looks like this: 要使用此API,客户端必须像这样调用它,因此client.php文件将如下所示:

<?php

$curl_header = array();
$curl_header[] = 'API-User-Name: test';
$curl_header[] = 'API-User-Password: password';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://mydomainname.com/api/access.php");
//curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_header);
$result = curl_exec($ch);


print_r($result);
curl_close($ch);


?>

Just use CURLOPT_HTTPHEADER : 只需使用CURLOPT_HTTPHEADER

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  'X-THING_ONE: abcdefghijklmnopqrstuvwxyz',
  'X-THING_TWO: 12345678910'
));

I prefer to set the header as an array outside of the curl_setopt like this: 我更喜欢将header设置为curl_setopt之外的数组,如下所示:

$curl_headers = array();

$curl_headers[] = 'X-THING_ONE: abcdefghijklmnopqrstuvwxyz';
$curl_headers[] = 'X-THING_TWO: 12345678910';

curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);

EDIT: Okay, it looks like you know how CURLOPT_HEADER works. 编辑:好的,看来您知道CURLOPT_HEADER工作原理。 But looking at your code there seems to be a typo right here. 但是,查看您的代码似乎在这里有错字。

curl_setopt($this->ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('API-Token: ' . $this->getToken() ));

Why do you have $this->ch in CURLOPT_HEADER & CURLOPT_HTTPHEADER but just $ch for CURLOPT_RETURNTRANSFER ? 为什么在CURLOPT_HEADERCURLOPT_HTTPHEADER$this->ch ,而对于CURLOPT_RETURNTRANSFER只有$ch呢? Shouldn't that be like this? 那不是这样吗?

curl_setopt($this->ch, CURLOPT_HEADER, true);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('API-Token: ' . $this->getToken() ));

EDIT: In addition to that typo, it seems that the original poster needs to know how to get the parameters on the receiving side: 编辑:除了打字错误,似乎原始海报需要知道如何在接收方获取参数:

Also how can I read the HTTP headers once the request is made? 发出请求后,如何读取HTTP标头?

Easy. 简单。 They are accessed via $_SERVER predefined variable in PHP. 可通过PHP中的$_SERVER预定义变量访问它们。 So you would grab them like this: 因此,您将像这样抓住它们:

$_SERVER['X-API-User-Name'];
$_SERVER['X-API-User-Password'];
$_SERVER['X-API-User-Token'];

And you can check what is passed while debugging by doing this: 通过执行以下操作,您可以检查调试时传递的内容:

echo '<pre>';
print_r($_SERVER);
echo '</pre>';

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

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