使用不带LocalStorage的弹出窗口的OAuth2隐式授权

时间:2017-10-12 13:46:19

标签: javascript angularjs internet-explorer oauth-2.0 microsoft-edge

我目前正在将第三方服务集成到我们的系统(客户端的AngularJS和ASP.NET Web API 2.0)中,这需要我们通过OAuth2.0对用户进行身份验证。

我目前正在使用隐式授权。但其中一个要求是支持Edge和> IE10。

起初我使用以下流程:

  1. 客户从WebAPI获取第三方服务登录网址
  2. WebAPI返回第三方服务登录URL然后客户端打开一个新的弹出窗口,其中包含登录URL(忽略浏览器弹出窗口阻止程序)以及返回我们应用程序的URL
  3. 验证后,用户将被重定向回我们的应用程序,该应用程序是一个空白页面,其中包含javascripts以从散列查询字符串中提取令牌,然后将访问令牌存储到本地存储
  4. 关闭弹出窗口
  5. 在我的控制器中,我订阅了存储更改事件。因此,当访问令牌设置为本地存储时,我的控制器将从本地存储中提取访问令牌并将其移至会话存储。
  6. 这一切都完美无缺,直到我在IE和Edge上测试它。哪个本地存储不同步。 localStorage in win8.1 IE11 does not synchronize

    为了使它适用于IE和Edge,我换掉了本地存储并改为使用cookie。然后,我有一个类似于以下函数的功能,而不是在更改事件上订阅存储,每秒检查一次cookie:

    setInterval(function(){
        // check cookie for cookie
        // if found, copy cookie to session storage
        // remove cookie
        // change state
    }, 1000);
    

    仅供参考:我们在会话存储中存储访问令牌,以防止用户打开多个标签来访问我们的网站。

    这种方法有效,但还有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

我过去实施的另一个选项是直接在窗口之间进行通信。

在父窗口上,在全局命名空间中公开一个函数:
window.oauthCallback = function(payload){ ... send to API }

在弹出窗口中,在oauth重定向回的页面上,查找window.opener并尝试直接调用该函数:
window.opener.oauthCallback(payload)
payload是一个对象,由在查询字符串中传回给你的oauth数据构成。大多数框架都可以为您提供这样的功能。

一个警告 - 如果在无法打开弹出窗口的环境中或窗口无法通信(例如ios webviews - 例如:点击facebook应用程序中的链接),那么您可以在同一窗口中进行重定向并将有效负载存储在localstorage中/ cookies或通过URL传递数据。