php cURL - подключить, если токен неверен, POST учетные данные для входа, преобразовать токен в новую переменную - PullRequest
0 голосов
/ 03 апреля 2020

API требует, чтобы в URL был действительный токен. Токен длится всего 10 минут.

первая часть моего скрипта:

<?php
    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, "https://rota.com/publicapi/XXtokenXX/date/2020-04-02/locations/");
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec ($curl);
    curl_close ($curl);

Мне нужен код для этого: Если ответ не является действительным токеном, тогда POST username = имя и пароль = передать rota.com/publicapi/login ответ будет таким:

<auth>
    <token>XXnew-tokenXX</token>
</auth>

Затем мне нужно будет повторно попытаться подключиться к API с помощью curl, используя этот новый токен в URL

Я вне моей глубины с этой частью сценария. Любая помощь приветствуется. Я увлеченный любитель, поэтому четкие инструкции и код приветствуются. Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

Вы захотите инкапсулировать cURL с помощью класса / метода или функции, чтобы вы могли легко повторить вызов. Если есть SDK, вероятно, стоит использовать. Если нет, попробуйте что-то вроде класса или инкапсуляции для очистки вашего кода.

Исходя из вашего собственного ответа, было бы лучше сделать функцию для части cURL:

# Contain all your call login inside this function,
# it keeps copy/paste down to minimum
function transmit($path, &$token, $attr = false, $method = 'get', $retry = true)
{
    # I would trim any leading/trailing separator because it will add it
    # automatically down below
    $path = trim($path, '/');
    # Fetch the token if it's not already set though ignore if login or
    # it will likely do an infinite loop
    if(empty($token) && $path != 'login')
        $token = fetchToken();
    # Since this will almost never change, just assign it here. If they ever change
    # then you just change it in this one spot instead of every instance in your
    # whole site where you copy/pasted it
    $endpoint = "https://rota.com/publicapi";
    # Create the query automatically
    if($attr) {
        $query = http_build_query($attr);
        $attr = '?'.$query;
    }
    # Create the final path
    # array_filter will remove empty attributes before imploding to a path
    $url = implode('/', array_filter([
        $endpoint,
        # Make sure to remove the token on a login call
        ($path == 'login')? false : $token,
        $path,
        $attr
    ]));        
    # Standard start here
    $curl = curl_init();
    # Compile the endpoint
    curl_setopt ($curl, CURLOPT_URL, $url);
    # If you want to specifically post, then accommodate. Just change "$method" in
    # when you call this function
    if($method == 'post') {
        # First check if there is a query already created
        if($query)
            curl_setopt($curl2, CURLOPT_POSTFIELDS, $query);
    }
    # Standard bit here
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    # Standard exec
    $response = curl_exec($curl);
    # Same ol
    curl_close($curl);
    # Just check for a portion of the string is necessary
    if(stripos($response, 'Token not valid') !== false) {
        # Fetch the token, if it fails, the program will throw exception
        $token = fetchToken();
        # If you have it set to retry original, it will try again
        if($retry) {
            # Set to stop retrying here. You don't want an infinite loop
            return transmit($path, $token, $attr, $method, false);
        }
        # Stop at this point
        return false;
    }
    # If token was valid, send back original response
    return $response;
}
# Create a function to fetch the token in the background
function fetchToken()
{
    # Send a post
    $fetchToken = transmit('login', false, [
        'username' => 'whatever',
        'password' => 'whatever'
    ], 'post', false);
    if($fetchToken) {
        # Convert the string to xml
        $xml = simplexml_load_string($output, null, LIBXML_NOCDATA);
        # Assign token to session for storage and then also update the session
        # for calls that happen after this call
        $token = trim($xml->token->__toString());
    }
    # Stop the program if token not fetched
    if(empty($token))
        throw Exception('An error occurred fetching the security token.');
    # Assign to session and return the token
    return $_SESSION['rota_token'] = $token;
}

Таким образом, вы должны быть в состоянии сделать это следующим образом:

# Try and get token
# If this line throws error, use:
# $token = ($_SESSION['rota_token'])? $_SESSION['rota_token'] : false;
$token = ($_SESSION['rota_token'])?? false;
# Fetch the data and make sure to pass the token to each transmit()
$data = transmit('date/2020-04-02/locations/', $token);

print_r($data);

В любом случае, я не проверил это полностью, поэтому в синтаксисе может быть что-то, но он сильно прокомментирован, поэтому вы можете получить то, что должно произойти .

0 голосов
/ 03 апреля 2020

это сработало. Пришлось обрезать новый токен, так как по какой-то причине при использовании его в строке URL он добавлял пробел к каждому концу.

<?php
 //try to use an existing token

    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, "https://rota.com/publicapi/XXtokenXX/date/2020-04-02/locations/");
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec ($curl);
    curl_close ($curl);


// if token invalid try and get a new one

if ($output == 'Token not valid or login credentials have expired') {


  $curl2 = curl_init();
    curl_setopt ($curl2, CURLOPT_URL, "https://rota.com/publicapi/login/");
     curl_setopt($curl2, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl2, CURLOPT_POSTFIELDS,
            "username=user&password=pass");
$output2 = curl_exec ($curl2);
  curl_close ($curl2);

  echo $output2 ;

 // create new url and display it 
  $curl3url =  "https://rota.com/$output2/date/2020-04-02/locations/" ;
  trim($curl3url," "); ;
  echo '<br>curl3url is<br>' ; echo $curl3url ;

// try connect to API with new  URL and print the output

  $curl_handle=curl_init();
  curl_setopt($curl_handle,CURLOPT_URL, $curl3url);
  curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
$output3 = curl_exec ($curl_handle);
    curl_close ($curl_handle);
  echo $output3 ;
}
else { 

  $xml = simplexml_load_string($output, null, LIBXML_NOCDATA) or die("Could not load xml");

}?>

...