Search code examples
javascriptoauth-2.0jwtthinktecture-ident-server

Oauth2 Implicit Flow with single-page-app refreshing access tokens


I am using Thinktecture AuthorizationServer (AS) and it is working great.

I would like to write a native javascript single page app which can call a WebAPI directly, however implicit flow does not provide a refresh token.

If an AJAX call is made, if the token has expired the API will send a redirect to the login page, since the data is using dynamic popups it will this will interrupt the user.

How does Facebook or Stackoverflow do this and still allow the javascript running on the page to call the APIs?

Proposed Solution

Does the below scenario sound sensible (assuming this can be done with iframes):

My SPA directs me to the AS and I obtain a token by Implicit Flow. Within AS I click allow Read data scope, and click Remember decision, then Allow button.

Since I have clicked Remember decision button, whenever I hit AS for a token, a new token is passed back automatically without me needing to sign in ( I can see FedAuth cookie which is remembering my decision and believe this is enabling this to just work).

With my SPA (untrusted app), I don't have a refresh-token only an access token. So instead I:

  1. Ensure user has logged in and clicked remember decision (otherwise iframe wont work)
  2. Call WebAPI, if 401 response try and get a new token by the below steps...
  3. Have a hidden iframe on the page, which I will set the URL to get a new access-token from the Authorisation Server.
  4. Get the new token from the iframe's hash-fragment, then store this in the SPA and use for all future WebAPI requests.

I guess I would still be in trouble if the FedAuth cookie is stolen.

Any standard or recommended way for the above scenario?


Solution

  • In Google o-Auth , the access token will only be valid for 1 hour, so you need to programmatically update your access token in each one hour, simple you can create web api to do so,you need to have a refresh token, and also that refresh token will not be expired , using c# code, I have done this.

     if (dateTimeDiff > 55)
                {
                    var request = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/oauth2/v3/token");
                    var postData = "refresh_token=your refresh token";
                    postData += "&client_id=your client id";
                    postData += "&client_secret=your client secrent";
                    postData += "&grant_type=refresh_token";
    
                    var data = Encoding.ASCII.GetBytes(postData);            
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.ContentLength = data.Length;
                    request.UseDefaultCredentials = true;
    
                    using (var stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                    var response = (HttpWebResponse)request.GetResponse();
                    string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
    
                }
    

    you need to save the last updated date time of the access token somewhere(say in database), so that , whenever you have to make a request , so you can subtract that with current date time , if it is more than 60 minutes , you need to call the webapi to get new token .