Solved

Getting OAU-213 Error When Using Newly Generated Token

  • 13 December 2019
  • 2 replies
  • 1827 views

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"

} ]

}


icon

Best answer by Phong1426275020 13 December 2019, 22:20

View original

2 replies

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:

Userlevel 1

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