Skip to main content

I'm having an issue where I authorize through the C# SDK, serialize that token to a database and then on subsequent calls, deseserialize it and try to use it and immediately get an OAU-213 Token Not Found Error. We want to forward phone calls on a dynamic basis so in the code below I instantiate a RestClient and then check to see if I have a token I can use, if I do, I then set it as the RestClient's token and make an API to forward the call. Whenever I use the token generated by calling rc.Authorize() my code works correctly, but if I store it to the database and then use the exact same token, I get the error down below. Any help would be appreciated.


Thanks!


public async Task<bool> ForwardPhoneCall(string userName, string firmId, string telephonySessionId, string partyId)
{
var phoneNumber = await _UserRepo.GetMainPhoneNumberFromUserName(userName, firmId);

if (phoneNumber != null)
{
RingCentralCredentials creds = await GetRingCentralCredentials(firmId);

ForwardTarget forwardTarget = new ForwardTarget() { phoneNumber = phoneNumber.FormatPhoneNoSpaces() };

using (var rc = new RestClient(creds.clientID, creds.clientSecret, creds.serverURL))
{
rc.token = await Authorize(creds, rc, firmId);
await rc.Restapi().Account().Telephony().Sessions(telephonySessionId).Parties(partyId).Forward().Post(forwardTarget);

return true;
}
}

return false;
}
 private async Task<RingCentral.TokenInfo> Authorize(RingCentralCredentials creds, RestClient rc, string firmId)
{
RingCentral.TokenInfo token;
var currentTime = DateTimeOffset.Now.ToUnixTimeSeconds();

if (creds?.tokenExpiration == null || string.IsNullOrEmpty(creds?.currentToken) || creds.tokenExpiration < currentTime)
{
token = await rc.Authorize(creds.username, creds.extension, creds.password);

creds.currentToken = JsonConvert.SerializeObject(token);
creds.tokenExpiration = DateTimeOffset.Now.ToUnixTimeSeconds() + token.expires_in - 300;

await SaveRingCentralCredentials(firmId, creds);
}
else
{
token = JsonConvert.DeserializeObject<RingCentral.TokenInfo>(creds.currentToken);
}

return token;
}


Here's the response:

RingCentral.RestException: Response:

StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.HttpConnection+HttpConnectionResponseContent, Headers:

{

Server: nginx

Date: Fri, 13 Dec 2019 17:54:41 GMT

Connection: keep-alive

X-Rate-Limit-Group: light

X-Rate-Limit-Limit: 50

X-Rate-Limit-Remaining: 49

X-Rate-Limit-Window: 60

WWW-Authenticate: Bearer realm="RingCentral REST API", error="OAU-213", error_description="Token not found"

RoutingKey: SJC12P01

RCRequestId: a3749b4e-1dd1-11ea-8694-005056bbcdd9

Content-Type: application/json

Content-Length: 154

Content-Language: en

}

Content: {

"errorCode" : "TokenInvalid",

"message" : "Token not found",

"errors" : [ {

"errorCode" : "OAU-213",

"message" : "Token not found"

} ]

}


yes, I printed both tokens and they are exactly the same and I can make calls within seconds of each other and the second one that reads the token from the database always fails.

I do use this same app for notifications, i.e. the AccountTelephony and Extension Telephony webhooks, but dont make any calls to the OAuth endpoint except to forward the phone. I noticed in my analytics that I have a bunch of calls to the revoke endpoint but never call that myself.

Here's my endpoint for the AccountTelephony webhook

        [Route("ringCentral/{firmId}")]
[HttpPost]
public async Task<ActionResult> GetAccountTelephony(string firmId)
{
_Logger.LogInformation("Starting Account Telephony");

HttpContext.Request.Headers.TryGetValue("Validation-Token", out StringValues validationToken);
HttpContext.Response.Headers.Add("Validation-Token", validationToken);

_Logger.LogInformation("Got Account Telephony Validation Token");

using (StreamReader reader = new StreamReader(HttpContext.Request.Body, Encoding.UTF8))
{
var requestBody = await reader.ReadToEndAsync();
.
.
.
return Ok();
}
}


Endpoints called by this app in past 24 hours:


I think this is the root cause of your problem.

using (var rc = new RestClient(creds.clientID, creds.clientSecret, creds.serverURL))
{
rc.token = await Authorize(creds, rc, firmId);
await rc.Restapi().Account().Telephony().Sessions(telephonySessionId).Parties(partyId).Forward().Post(forwardTarget);

return true;
}

You authorize your app inside the "using" brackets, and when your code exists, the object is disposed and the token will be revoked by the SDK

public async void Dispose()
{
await Revoke();
}

Try avoid the "using" will solve the problem.


Reply