具有单页应用刷新访问令牌的 Oauth2 隐式流

我正在使用 Thinktecture AuthorizationServer (AS),它运行良好.

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

我想写一个可以直接调用 WebAPI 的原生 javascript 单页应用,但是隐式流不提供刷新令牌.

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.

如果进行 AJAX 调用,如果令牌已过期,API 将发送重定向到登录页面,因为数据使用动态弹出窗口,这将中断用户.

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.

Facebook 或 Stackoverflow 如何做到这一点,并且仍然允许页面上运行的 javascript 调用 API?

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

建议的解决方案

下面的场景听起来合理吗(假设这可以通过 iframe 完成):

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

我的 SPA 将我定向到 AS,我通过隐式流获得了一个令牌.在 AS 我点击允许 Read data 范围,然后点击 Remember decision,然后点击 Allow 按钮.

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.

由于我点击了 Remember decision 按钮,每当我点击 AS 获取令牌时,都会自动传回一个新令牌,而无需我登录(我可以看到 FedAuth cookie 正在记住我的决定并相信这使它能够正常工作).

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).

使用我的 SPA(不受信任的应用程序),我没有刷新令牌,只有访问令牌.所以我改为:

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

  1. 确保用户已登录并点击记住决定(否则 iframe 将无法工作)
  2. 调用 WebAPI,如果 401 响应尝试通过以下步骤获取新令牌...
  3. 在页面上有一个隐藏的 iframe,我将设置 URL 以从授权服务器获取新的访问令牌.
  4. 从 iframe 的哈希片段中获取新令牌,然后将其存储在 SPA 中并用于所有未来的 WebAPI 请求.

如果 FedAuth cookie 被盗,我想我仍然会遇到麻烦.

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

上述场景有什么标准或推荐的方法吗?

Any standard or recommended way for the above scenario?

推荐答案

在 Google o-Auth 中,访问令牌的有效期只有 1 小时,因此您需要每隔一小时以编程方式更新您的访问令牌,简单您可以创建web api来做到这一点,你需要一个刷新令牌,并且刷新令牌不会过期,使用c#代码,我已经做到了.

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();

            }

您需要将访问令牌的最后更新日期时间保存在某处(例如在数据库中),这样,每当您必须发出请求时,您可以用当前日期时间减去它,如果它超过 60分钟,你需要调用webapi来获取新的token.

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 .

相关文章