具有Angular前端的Web Api OAuth - 无法处理302重定向

时间:2014-02-01 17:38:17

标签: angularjs oauth asp.net-web-api

我坚持这个问题试图用OAuth(在knockout.js中)将Web Api SPA模板重写为angular.js。

当我点击外部登录按钮时,会发生一系列请求,最终导致

Authentication.SignIn(claimsIdentity);

这很好!但是,在我return Ok()之后,我被重定向到外部登录(Google)。在我使用Google登录后,他们的授权服务器会将302重定向响应到以下位置:

 http://localhost:59936/access_token=xxxx&token_type=bearer&expires_in=1209600&state=yyyy

在淘汰赛中查看SPA模板我应该解析令牌的url,并使用访问令牌调用getUserInfo()。

然而,发生的事情是链接只是塞进我的浏览器网址栏,而Angular对此无动于衷。我的httpInterceptor不会触发,$ routeChanged也不会触发,我认为它会愚蠢/肮脏/并且可能无法生成$routeProvider.when("/access_token")

我在1.2.9角度(我看到有人提到角度的错误,我无法找到关于它的http拦截器处理302并且它在1.2.9中修复但似乎不是这样。

怎么办?

编辑:实际上,考虑如何构建代码实际上,使用routeProvider捕获它实际上并不是那么脏。这是因为HomeController看起来像这样:

function HomeController(...) {

   //Parses the url above
   var fragment = getFragment();

   ... All kinds of fragment checks (fragment.access_token, fragment.state, etc)...
}

问题是当这个URL被填充到浏览器中时,HomeController没有被实例化。

有没有办法将上面的网址与路线相匹配?像when('/access_token*rest')之类的东西 - 但这不起作用。

我能想到的潜在解决方法是捕获$locationChangeStart中的url更改并将access_token填充到本地/会话存储中,但这需要大量代码重构,因为所有逻辑已经在HomeController中。最好的方法就是让它在被击中时实例化。

不满意的解决方法:这是另一种解决方法,但我真的不满意。这很糟糕,需要进行大量的重组。

 app.run(['$rootScope', '$location', '$http', '$controller', 'AuthenticationService', 

    '$window', 'StorageService', //HomeController Dependencies

    function ($rootScope,
              $location,
              $http,
              $controller,
            AuthenticationService,

        $window, StorageService)
    {       
        $rootScope.$on("$locationChangeStart", function (event, next, current) {
            if (next.indexOf("access_token") > -1) {

                var homeController = $controller(Controllers.Authentication.HomeController, {
                    '$rootScope': $rootScope,
                    '$scope': {},
                    '$window': $window,
                    '$location': $location,
                    'AuthenticationService': AuthenticationService,
                    'StorageService': StorageService  
                });
            }
        });
    }

1 个答案:

答案 0 :(得分:2)

  

有没有办法将上面的网址与路线相匹配?像什么时候('/ access_token * rest') - 但这不起作用。

如果您的网址为http://localhost:59936/?access_token=xxxx&token_type=bearer&expires_in=1209600&state=yyyy(请注意添加的?),那么路由器可以像$routeProvider.when('/')那样匹配它(因为路由器将忽略参数字符串)然后在您的控制器中可以解析url参数。

此外部登录是否会导致包含角度应用的网页重定向到外部网页?如果是这种情况,那么您的应用程序将被卸载,这可能并不理想。要处理外部登录,我通常会打开一个弹出窗口,以便我的应用程序不会被卸载。