ChatGPT解决这个技术问题 Extra ChatGPT

How to identify if the OAuth token has expired?

My iOS mobile app consumes services that are implemented with the OAuth2.0 protocol. The OAuth access token comes along with a refresh token and an expires_in field. I saved the refresh token and access token expiration time in my app but don't have a good idea on when to use them.

So what is the usual and best practice of using this expires_in?

How do I identify that my access token is expired?

Is there a common web service error format which says my access token is expired?


C
Community

Here's information on OAuth 2.0 token refresh.

Expires In Definition

The OAuth 2.0 standard, RFC 6749, defines the expires_in field as the number of seconds to expiration:

expires_in: RECOMMENDED. The lifetime in seconds of the access token. For example, the value "3600" denotes that the access token will expire in one hour from the time the response was generated. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value.

Token Refresh Handling: Method 1

Upon receiving a valid access_token, expires_in value, refresh_token, etc., clients can process this by storing an expiration time and checking it on each request. This can be done using the following steps:

convert expires_in to an expire time (epoch, RFC-3339/ISO-8601 datetime, etc.) store the expire time on each resource request, check the current time against the expire time and make a token refresh request before the resource request if the access_token has expired

An example implementation is the Go oauth2 library which converts the expires_in value to a RFC 3339 date-time in the Token expiry property. expiry isn't defined by the OAuth 2.0 standard but is useful here.

When checking the time, be sure you are the same time, for example, using the same timezone by converting all times to epoch or UTC timezone.

In addition to receiving a new access_token, you may receive a new refresh_token with an expiration time further in the future. If you receive this, you should store the new refresh_token to extend the life of your session.

Token Refresh Handling: Method 2

Another method of handling token refresh is to manually refresh after receiving an invalid token authorization error. This can be done with the previous approach or by itself.

If you attempt to use an expired access_token and you get an invalid token error, you should perform a token refresh (if your refresh token is still valid). Since different services can use different error codes for expired tokens, you can either keep track of the code for each service or an easy way to refresh tokens across services is to simply try a single refresh upon encountering a 4xx error.

Invalid Access Token Errors

Below are some error codes from popular services:

Facebook: Error 467 Invalid access token - Access token has expired, been revoked, or is otherwise invalid - Handle expired access tokens. LinkedIn: Error 401 Unauthorized. PayPal: Error 401 Unauthorized.

Implementations

The Zapier service is one service that implements the refresh after authorization error retry.

https://i.stack.imgur.com/P8K0z.png

Refresh Token Expiration

If your refresh_token has also expired, you will need to go through the authorization process again.

The OAuth 2.0 spec doesn't define refresh token expiration or how to handle it, however, a number of APIs will return a refresh_token_expires_in property when the refresh token does expire. Different APIs will handle refresh token expiration differently so it's important to review the docs per API, but generally you may receive a new refresh token when you refresh your access token. Expiration should be handled in a similar way such as converting refresh_token_expires_in to a RFC 3339 date-time refresh_token_expiry value.

Some examples include LinkedIn, eBay, and RingCentral. In the LinkedIn API, when you refresh access tokens, you will receive a refresh token with a decreasing refresh_token_expires_in property targeting the original refresh token expiry time until you are required to auth again. The RingCentral API will return refresh tokens with a static time so the user does not have to auth again if token refreshes and refresh token updates are done consistently.


Hi, great thanks for your reply! While checking the expire time, what if the user changes the device time? Will it not lead to refreshing the access token too often? And with respect to checking the invalid token error, do you have any idea on the response code and the error format that oAuth server will return? And will this be error response be same for all oAuth servers?
What are some use cases for often occurring device time changes? Timezone changes should be handled automatically. Since invalid token error code isn't defined in the standard, different services have chosen different error codes now listed above. A simple refresh approach may be to try a single refresh upon a 4xx error as mentioned.
Spotify returns a 401 unauthorized
Late to the party, but how do you know if the refresh_token is not valid? :O
IETF RFC 6749 does not define refresh token expiration or how to handle it but a number of APIs implement a refresh_token_expires_in property and I've updated the answer with this info.
G
Gary Archer

Would recommend Method 2 above since a 401 can happen for multiple reasons such as renewing a token signing certificate or clock differences:

Check for a 401 after every API request

Get a new token - once only

Retry the API request - once only

I've implemented plenty of successful OAuth clients and have always used this technique - and avoided ever reading the expires_in field in my client side code


I was going to implement code in my app the check the expires_in field but ran into a lot of problems with timezones and users changing device times. So I'm going to implement my NetworkingClient how you stated above.
Shouldn't the expiration returned from the token issuer be indifferent to the users timezone? I'd expect it to be UTC.
R
Robert

The question specifies iOS but as a general principle for any toolset, for server based solutions store the token in the server memory cache and set the cache expiry datetime to the same as the token's expiry.

Call the function below prior to any other endpoint where the auth token is required.

This way it gets the token from the cache or gets a new token if the cache has expired (which is the same time as the token itself expires).

For .NET:

    private async Task<string> GetAuthToken()
    {
        string cacheKey = "AuthToken";

        if (!_memoryCache.TryGetValue(cacheKey, out string authToken))
        {
            // Token not in cache, so get fresh one:

            // Do call for token
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, *url*);

            // Add Headers
            ...
            // Make call
            var response = await client.SendAsync(request);
            string responseContent = await response.Content.ReadAsStringAsync();

            // Check the call success/failure
            if (!response.IsSuccessStatusCode)
            {
                return null;
            }

            JObject authObj = JObject.Parse(responseContent);
            authToken = (string)authObj["access_token"];
            string authTokenExpires = (string)authObj["expires_in"];

            // Save data in cache.
            MemoryCacheEntryOptions staticDataCacheMemoryOptions = new MemoryCacheEntryOptions()
                    // Keep in cache until expired by Provider
                    .SetAbsoluteExpiration(DateTime.Now.AddSeconds(Convert.ToInt32(authTokenExpires)));

            _memoryCache.Set(cacheKey, authToken, staticDataCacheMemoryOptions);
        }

        return authToken;
    }

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now