I'm implementing facebook ouath login in angularjs without SDK.
Everything works as expected except one thing.
When user click on login button, which redirects to facebook login page, after successfull login, facebook fires redirect_uri URL, and user is again in the app.
Problem is, that ui-router (probably) replaces '?' with '#' in path, so
http://localhost/fbauth?access_token=xxx&code=yyy
becomeshttp://localhost/fbauth#access_token=xxx&code=yyy
Because of that, i cannot use $stateParams
to get object with query params.
Suprisingly, when I manually enter in browser or click link to
http://localhost/fbauth?access_token=xxx&code=yyy
everything works properly, and ui-router does not replace '?' with '#'.
I guess, that it's related to redirection scenario itself.
Can someone point me what I do wrong, or how to change ui-router behaviour in this case?
This is the state, that handles fb redirect:
.state('fbauth', {
url: '/fbauth?access_token&code&expires_in',
templateUrl: 'static/public/public.html',
controller: 'publicCtrl'
});
PS ui-router is set to work in html5 mode with $locationProvider.html5Mode(true);
You can add this resolve function to your state, which will replace a hash url with the query string url:
resolve: {
'urlFix': ['$location', function($location){
$location.url($location.url().replace("#","?"));
}]
}
/fbauth#access_token=123456&code=abcde&expires_in=99999999
would be redirected automatically/fbauth?access_token=123456&code=abcde&expires_in=99999999
$stateParams
would be populated correctly. {access_token: "123456", code: "abcde", expires_in: "99999999"}
$location.url()
doesn't update if the location matches already, so the state won't redirect when there is no #
present. <!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<meta charset="utf-8">
<title>FBAUTH</title>
</head>
<body ng-app="app">
<base href="/">
<div ui-view></div>
<script>
angular.module('app', ['ui.router'])
.controller('publicCtrl', ['$scope','$stateParams', function($scope, $stateParams) {
// $stateParams should be correctly set (even for hash route)
console.log($stateParams);
}])
.config(['$locationProvider','$stateProvider', function($locationProvider, $stateProvider){
$stateProvider
.state("fbauth",
{
url: '/fbauth?access_token&code&expires_in',
templateUrl: 'fbauth.html',
controller: 'publicCtrl',
resolve: {
'urlFix': ['$location', function($location){
$location.url($location.url().replace("#","?"));
}]
}
});
$locationProvider.html5Mode(true);
}]);
</script>
</body>
</html>
I would not prefer passing query parameters(using ? mark) in client side routing. Instead you can use route/state params as follows:
http://localhost/#/fbauth/access_token/:access_token/code/:code
and you can access these values using $stateParams
. e.g. ($stateParams.access_token
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With