网页API的OAuth与角前端 - 无法处理302重定向重定向、网页、OAuth、API

2023-09-14 00:26:17 作者:我绝对不会去想你!

林停留在这一个问题试图重写使用OAuth的网页API SPA模板(在knockout.js)到angular.js。

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

  Authentication.SignIn(claimsIdentity); 

这是好!不过,之后我返回OK()我重定向到外部登录(谷歌)。之后,我与谷歌的签到授权服务器以302响应重定向到以下位置:

 的http://本地主机:59936 / =的access_token XXXX&安培; token_type =承载和放大器; expires_in = 1209600&放大器;状态= YYYY 
Azure AD 二 调用受Microsoft 标识平台保护的 ASP.NET Core Web API 上

综观淘汰赛SPA模板,我应该来解析令牌的网址,并与访问令牌getUserInfo()的调用。

但什么情况是,链接只是被塞到我的浏览器地址栏和角度是无视它。我httpInterceptor不火,既没有做$ routeChanged,我认为这将是愚蠢/肮脏/大概不会工作做出 $ routeProvider.when(/的access_token)

我在1.2.9角(我看到有人提到一个错误的角度,我无法找到关于它的HTTP 302拦截处理和它的固定1.2.9,但似乎并不如此。

该怎么办?

编辑:其实,想着code是如何构成它难道不居然是脏的,以便能够赶上使用routeProvider。这是因为的HomeController 看起来是这样的:

 函数的HomeController(...){   //解析上面的网址   变种片段= getFragment();   ......各种片段检查(fragment.access_token,fragment.state等)...} 

问题是,当这个网址被塞进了浏览器的HomeController不会被实例化。

有什么办法来匹配上述网址的路线?类似时,('/ *的access_token其余') --However这是行不通的。

我能想到的一个潜在的解决方法是捕捉 $ locationChangeStart 的URL变化和东西的的access_token到本地/会话存储,但是这将需要大量的$ C的因为所有的逻辑$ C重组已经在HomeController中。最好将只是把它实例化时URL被击中。

不满意解决方法:这里还有一个解决办法,但林真的不喜欢它。它的hackish,并需要大量的重组。

  app.run(['$ rootScope','$的位置,$ HTTP,$控制器,的AuthenticationService',    '$窗口','StorageService',// HomeController的依赖    功能($ rootScope,              $位置,              $ HTTP,              $控制器,            的AuthenticationService,        $窗口,StorageService)    {        $ rootScope。在$($ locationChangeStart功能(事件,接下来,电流){            如果(next.indexOf(的access_token)-1个){                VAR的HomeController = $控制器(Controllers.Authentication.HomeController,{                    '$ rootScope':$ rootScope,                    '$范围:{},                    '$窗口':$窗口,                    '$位置:$位置,                    '的AuthenticationService:的AuthenticationService,                    StorageService':StorageService                });            }        });    } 

解决方案   

有什么办法来匹配上述网址的路线?就像当('/ *的access_token其余')的东西--However这是行不通的。

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

这是外部登录过含有角的应用重定向到外部网页的页面?如果是这样的话,那么你的应用程序将被卸载,这可能并不理想。为了处理外部登录,我通常会打开一个弹出窗口,让我的应用程序没有得到卸载。

Im stuck on this one issue trying to rewrite the Web Api SPA template with OAuth (in knockout.js) into angular.js.

When I click an external login button a series of requests take place that eventually result in

Authentication.SignIn(claimsIdentity);

This is good! However, right after I return Ok() I get redirected to the external login (Google). After I signin with Google their authorization servers respond with a 302 redirect to the following location:

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

Looking at the SPA template in knockout I'm supposed to parse the url for the token, and make a call to getUserInfo() with the access token.

However what happens is that link just gets stuffed into my browser url bar and Angular is oblivious to it. My httpInterceptor does not fire, neither does $routeChanged, and I think it would be silly/dirty/ and probably wont work to make a $routeProvider.when("/access_token")

I'm in 1.2.9 angular (I saw someone mention a bug in angular that i cant find regarding it's http interceptor handling of 302 and that it's fixed in 1.2.9 but does not seem to be the case.

What to do?

EDIT: Actually, thinking about how the code is structured it wouldnt actually be that dirty to be able to catch that using routeProvider. This is because the HomeController looks something like this:

function HomeController(...) {

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

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

The problem is the HomeController does not get instantiated when this URL gets stuffed into the browser.

Is there any way to match the above url to a route? Something like when('/access_token*rest') --However this does not work.

A potential workaround I can think of is to catch the url change in $locationChangeStart and stuff the access_token into local/session storage but this would require a lot of code restructuring since all of the logic is already in the HomeController. The best would be just get it to instantiate when that url gets hit.

Unsatisfactory workaround: Here's another the workaround but Im really not happy with it. It's hackish and requires a lot of restructuring.

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

解决方案

Is there any way to match the above url to a route? Something like when('/access_token*rest') --However this does not work.

If your URL were http://localhost:59936/?access_token=xxxx&token_type=bearer&expires_in=1209600&state=yyyy (notice the added ?) then the router could match it like this $routeProvider.when('/') (since the router will ignore the param string) then in your controller you can parse the url parameters.

Is this external login causing the page containing your angular app to redirect to the external webpage? If this is the case, then your app will be unloaded, which probably isn't ideal. To handle external login, I usually open a popup window so that my app doesn't get unloaded.