php-cURL-connect,如果令牌无效,POST登录凭据,将令牌输出转换为新变量



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=name&password=传递到rota.com/publicapi/login响应将是:

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

然后,我需要重新尝试使用curl连接到API,在URL 中使用这个新令牌

我对剧本的这一部分感到力不从心。感谢您的帮助。我是一个狂热的业余爱好者,所以清晰的指令和代码是值得赞赏的。提前感谢

这是有效的。由于某种原因,当在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");

}?>

您需要用类/方法或函数封装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);

无论如何,我还没有完全测试过这一点,所以语法中可能有一些东西,但它有大量的注释,所以你可以得到应该发生的事情。

相关内容

最新更新