Skip to main content
Solved

Getting OAU-213 Error When Using Newly Generated Token

  • December 13, 2019
  • 2 replies
  • 1874 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"

} ]

}


Best answer by PhongVu

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.

View original
Did this thread help you find an answer to your question?

2 replies

  • Author
  • New Participant
  • 1 reply
  • December 13, 2019

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:


PhongVu
Community Manager
Forum|alt.badge.img
  • Community Manager
  • 2317 replies
  • Answer
  • December 13, 2019

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


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings