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

后端 未结 4 1410
旧时难觅i
旧时难觅i 2021-02-01 03:29

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, how

相关标签:
4条回答
  • 2021-02-01 03:48

    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 .

    0 讨论(0)
  • 2021-02-01 03:53

    I understand that your problem is that the user will experience an interruption when the access token has expired, by a redirection to the login page of the authorization server. But I don't think you can and should get around this, at least, when using the implicit grant.

    As I'm sure you already know, the implicit grant should be used by consumers that can NOT keep their credentials secret. Because of this, the access token that is issued by an authorization server should have a limited ttl. For instance google invalidates their access token in 3600 sec. Of course you can increase the ttl, but it should never become a long lived token.

    Also something to note is that in my opinion the user interruption is very minimal, i.e if implemented correctly, the user will only have to authenticate once with the authorization server. After doing that (for example the first time when also authorizing the application access to whatever resources the user controls) a session will be established (either cookie- or token based) and when the access token of the consumer (web app using implicit grant) expires, the user will be notified that the token has expired and re authentication with the authorization server is required. But because a session already has been established, the user will be immediately redirected back to the web app.

    If however this is not what you want, you should, in my opinion, consider using the authorization code grant, instead of doing complicated stuff with iframes. In that case you need a server side web application because then you can keep your credentials secret and use refresh tokens.

    0 讨论(0)
  • 2021-02-01 03:56

    Not sure if I understand your question but,

    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.

    Summarize facts,

    refresh token is sometimes used to be a part of A: Authorization Grant

    https://tools.ietf.org/html/rfc6749#section-1.5

    and as you said in implicit flow you dont get back refresh token, but only in Authorization Grant part

    https://tools.ietf.org/html/rfc6749#section-4.2.2

    so you can get back refresh token when issuing access token (refresh tokens are always optional)

    https://tools.ietf.org/html/rfc6749#section-5.1

    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.

    1) SPA(you) have no idea if user selected remember decision. Its in AS direction and should be complete blackbox. Skip this step.

    2) You can try to use access token and wait for result, always.

    3) If access token has expired and you dont have refresh token, you still can create hidden iframe and and try to get new access token.

    4) Lets assume your AS provide option to remember decision and wont change it in future, then: your iframe will get new access token without user interaction, then you will get result back in some unknown time limit. Result can be checked by setInterval for read specific cookie or iframe postmessage. If you dont get back data in time limit, then one from following scenarios occured:

    • lag, AS is slow, connection is slow or time limit is too tight
    • user didnt select remember decision

    In this case:

    5) show iframe with login

    I consider scenario above as good practise if AS doesnt provide refresh tokens, but I also guess every AS like that wont provide remember option as well.

    StackOverflow <---> Google scenario (I can only guess)

    1) User login, authorization request occured

    2) User logs in, SO gets access token

    3) SO tries to use access token

    4) SO gets back result + refresh token

    5) SO saves refresh token

    6) SO has permanent access to users Google account

    0 讨论(0)
  • 2021-02-01 03:59

    Sounds like you need to queue requests in the event that an access token expires. This is more or less how Facebook and Google do it. A simple way using Angular would be to add a HTTP Interceptor and check for HTTP401 responses. If one is returned, you re-authenticate and queue any requests that come in after until the authentication request has completed (i.e. a promise). Once that's done, you can then process the outstanding queue with the newly returned access token from your authentication request using your refresh token.

    Happy Coding.

    0 讨论(0)
提交回复
热议问题