News & Announcements User Community Developer Community

Welcome to the RingCentral Community

Please note the community is currently under maintenance and is read-only.

Search
Make sure to review our Terms of Use and Community Guidelines.
  Please note the community is currently under maintenance and is read-only.
Home » Developers
OAU-213 Token not found, token is failing to refresh
Tags: authentication
Jul 15, 2020 at 5:30pm   •   2 replies  •  0 likes
Alex Schittko

I'm having an issue building out my first RingCentral app. Using PHP 7 with the RingCentral PHP SDK fetched via Composer.

The idea here is the app will need to be authorized once upon startup, and will stay logged in as long as the app is running, allowing any user who queries the app to achieve a result from RingCentral, parsed in a manner acceptable for my org.

When the app goes through the oauth2 login flow, upon success it will store the access token to a cache (Redis):


if (isset($_REQUEST['oauth2callback'])){
 if (!isset($_GET['code'])) {
 return;
 }
 $qs = $platform->parseAuthRedirectUrl($_SERVER['QUERY_STRING']);
 $qs["redirectUri"] = $RINGCENTRAL_REDIRECT_URL;

 $platform->login($qs);
 $_SESSION['sessionAccessToken'] = $platform->auth()->data();
 
 $redis->set("accessToken", serialize($_SESSION['sessionAccessToken']));


On every subsequent page load that requires the app to be authenticated with RingCentral, we check if the token exists, and set it on the platform object if appropriate. Else, we'll redirect to the login flow.

$rcsdk = new SDK($RINGCENTRAL_CLIENT_ID, $RINGCENTRAL_CLIENT_SECRET, $RINGCENTRAL_SERVER_URL);
$platform = $rcsdk->platform();

if (! $redis->get("accessToken")) { 
 header("Location: " . $host);
}
else {
 session_start();
 $_SESSION['sessionAccessToken'] = $redis->get('accessToken');
 $platform->auth()->setData( unserialize( $_SESSION['sessionAccessToken'] ) );
}


Based on the README for the php SDK, the platform object is capable of refreshing the token itself in the event that the access token expires.


The app has a component where it runs a cron job periodically to seed it's database with fresh data from the RC API:

<?php

// Log in to the API
require(__DIR__ . '/vendor/autoload.php');
require_once("./config/configs.php");
require_once("./database/redis.php");

use RingCentral\SDK\Http\HttpException;
use RingCentral\SDK\Http\ApiResponse;
use RingCentral\SDK\SDK;

$rcsdk = new SDK($RINGCENTRAL_CLIENT_ID, $RINGCENTRAL_CLIENT_SECRET, $RINGCENTRAL_SERVER_URL);
$platform = $rcsdk->platform();

if (! $redis->get("accessToken")) { 
 die("Cron is exiting because the app is not logged in");
}

// Get the call records
$platform->auth()->setData( unserialize( $redis->get("accessToken") ) );
try { 
 $apiResponse = $rcsdk->platform()->get('/restapi/v1.0/account/~/active-calls', array( "Direction" => "Inbound", "view" => "Detailed")) ;
}
catch (\RingCentral\SDK\Http\ApiException $e) {
 // Getting error messages using PHP native interface
 print 'RC API Error: ' . $e->getMessage() . PHP_EOL;
 die();
}
// Store to DB
$redis->set("callLog", serialize($apiResponse->json()->records));

echo "Refreshed the call data!";
?>


After about an hour of leaving the application running, the cron starts dieing out on:

RC API Error: Token not found

I was able to dump the request and response objects when I get a Token not found error:

Expected HTTP Error: Token not found
GuzzleHttp\Psr7\Request Object
(
[method:GuzzleHttp\Psr7\Request:private] => POST
[requestTarget:GuzzleHttp\Psr7\Request:private] =>
[uri:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Uri Object
(
[scheme:GuzzleHttp\Psr7\Uri:private] => https
[userInfo:GuzzleHttp\Psr7\Uri:private] =>
[host:GuzzleHttp\Psr7\Uri:private] => platform.ringcentral.com
[port:GuzzleHttp\Psr7\Uri:private] =>
[path:GuzzleHttp\Psr7\Uri:private] => /restapi/oauth/token
[query:GuzzleHttp\Psr7\Uri:private] =>
[fragment:GuzzleHttp\Psr7\Uri:private] =>
)

[headers:GuzzleHttp\Psr7\Request:private] => Array
(
[Host] => Array
(
[0] => platform.ringcentral.com
)

[Authorization] => Array
(
[0] => Basic <I TRUNCATED THE KEY FROM THIS OUTPUT>
)

[Content-Type] => Array
(
[0] => application/x-www-form-urlencoded
)

[accept] => Array
(
[0] => application/json
)

[User-Agent] => Array
(
[0] => Unnamed/0.0.0 Linux/4.4.0-18362-Microsoft PHP/7.2.24-0ubuntu0.18.04.6 RCPHPSDK/2.2.3
)

[RC-User-Agent] => Array
(
[0] => Unnamed/0.0.0 Linux/4.4.0-18362-Microsoft PHP/7.2.24-0ubuntu0.18.04.6 RCPHPSDK/2.2.3
)

)

[headerNames:GuzzleHttp\Psr7\Request:private] => Array
(
[authorization] => Authorization
[content-type] => Content-Type
[accept] => accept
[user-agent] => User-Agent
[rc-user-agent] => RC-User-Agent
[host] => Host
)

[protocol:GuzzleHttp\Psr7\Request:private] => 1.1
[stream:GuzzleHttp\Psr7\Request:private] => GuzzleHttp\Psr7\Stream Object
(
[stream:GuzzleHttp\Psr7\Stream:private] => Resource id #68
[size:GuzzleHttp\Psr7\Stream:private] => 408
[seekable:GuzzleHttp\Psr7\Stream:private] => 1
[readable:GuzzleHttp\Psr7\Stream:private] => 1
[writable:GuzzleHttp\Psr7\Stream:private] => 1
[uri:GuzzleHttp\Psr7\Stream:private] => php://temp
[customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
(
)

)

)
GuzzleHttp\Psr7\Response Object
(
[reasonPhrase:GuzzleHttp\Psr7\Response:private] => Bad Request
[statusCode:GuzzleHttp\Psr7\Response:private] => 400
[headers:GuzzleHttp\Psr7\Response:private] => Array
(
[Server] => Array
(
[0] => nginx
)

[Date] => Array
(
[0] => Wed, 15 Jul 2020 23:08:13 GMT
)

[Content-Type] => Array
(
[0] => application/json;charset=utf-8
)

[Content-Length] => Array
(
[0] => 161
)

[Connection] => Array
(
[0] => keep-alive
)

[X-Application-Context] => Array
(
[0] => application:8080
)

[Content-Language] => Array
(
[0] => en
)

[RCRequestId] => Array
(
[0] => 0edf196e-c6f0-11ea-8fa3-005056af98c7
)

[Pragma] => Array
(
[0] => no-cache
)

[Cache-Control] => Array
(
[0] => no-store
)

[AceRoutingKey] => Array
(
[0] => iad41-c01-ace02.4d0d56f5-b9cf-11ea-afde-0050568d0f78
)

[RoutingKey] => Array
(
[0] => SJC01P06
)

)

[headerNames:GuzzleHttp\Psr7\Response:private] => Array
(
[server] => Server
[date] => Date
[content-type] => Content-Type
[content-length] => Content-Length
[connection] => Connection
[x-application-context] => X-Application-Context
[content-language] => Content-Language
[rcrequestid] => RCRequestId
[pragma] => Pragma
[cache-control] => Cache-Control
[aceroutingkey] => AceRoutingKey
[routingkey] => RoutingKey
)

[protocol:GuzzleHttp\Psr7\Response:private] => 1.1
[stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream Object
(
[stream:GuzzleHttp\Psr7\Stream:private] => Resource id #76
[size:GuzzleHttp\Psr7\Stream:private] =>
[seekable:GuzzleHttp\Psr7\Stream:private] => 1
[readable:GuzzleHttp\Psr7\Stream:private] => 1
[writable:GuzzleHttp\Psr7\Stream:private] => 1
[uri:GuzzleHttp\Psr7\Stream:private] => php://temp
[customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
(
)

)

)


So, clearly, the token refreshing is either
a) not happening
b) happening in a context that doesn't push the token back up to my client

Can I be provided with some sample code to manually refresh the token?
Or guidance on storing the refreshed token so that the app will function?
Seeing as I already run cron jobs to seed data, adding another (check if token is refreshed ? do token refresh) block of code will be trivial at this point.

Many thanks!

2 Answers
answered on Jul 21, 2020 at 1:56pm  

Yeah, that was the solution. I needed to store the token at the end of every cron run, so that in the event that the platform refreshed the token, I will be storing the new token.


 0
answered on Jul 15, 2020 at 7:50pm  

Aha! I think I might be on to something

Just because the platform is capable of refreshing the token, doesn't mean I'm storing the refreshed token.


A few lines of code to the cron job before we start calling the API for active calls:

// Get the call records
$platform->auth()->setData( unserialize( $redis->get("accessToken") ) );
if ( ! $platform->loggedIn() ) {
    $platform->refresh();
    error_log("I refreshed my own token!");
}

try { 
    $apiResponse = $rcsdk->platform()->get('/restapi/v1.0/account/~/active-calls', array( "Direction" => "Inbound", "view" => "Detailed")) ;
}

And an extra line to the end, when stuff gets stored to the cache:

// Store to DB
$redis->set("callLog", serialize($apiResponse->json()->records));

// Store the token object back to cache.
// The token object will refresh if needed.
// If the token was refreshed, we will need to store the new one, like this.
$redis->set("accessToken", serialize($platform->auth()->data()));

I'm going to let this cron job run overnight and see if this works the way it's intended now


 0



A new Community is coming to RingCentral!

Posts are currently read-only as we transition into our new platform.

We thank you for your patience
during this downtime.

Try Workflow Builder

Did you know you can easily automate tasks like responding to SMS, team messages, and more? Plus it's included with RingCentral Video and RingEX plans!

Try RingCentral Workflow Builder

PRODUCTS
RingEX
Message
Video
Phone
OPEN ECOSYSTEM
Developer Platform
APIs
Integrated Apps
App Gallery
Developer support
Games and rewards

RESOURCES
Resource center
Blog
Product Releases
Accessibility
QUICK LINKS
App Download
RingCentral App login
Admin Portal Login
Contact Sales
© 1999-2024 RingCentral, Inc. All rights reserved. Legal Privacy Notice Site Map Contact Us