具有单页应用刷新访问令牌的 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:
- 确保用户已登录并点击记住决定(否则 iframe 将无法工作)
- 调用 WebAPI,如果 401 响应尝试通过以下步骤获取新令牌...
- 在页面上有一个隐藏的 iframe,我将设置 URL 以从授权服务器获取新的访问令牌.
- 从 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 .
相关文章