I'm stuck on this one issue trying to rewrite the Web Api SPA template with OAuth (in knockout.js) into AngularJS.
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 sign-in 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 won't 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 can't find regarding its 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 wouldn't 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 I'm 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
});
}
});
}