diff --git a/example/demo_redirect.html b/example/demo_redirect.html new file mode 100644 index 0000000..9d784d5 --- /dev/null +++ b/example/demo_redirect.html @@ -0,0 +1,33 @@ + + + + + Client-side authentication demo with redirect + + + +
+
+

You're authenticated!

+ +

Access token

+
{{accessToken}}
+ +
+

Expiry

+

Expires in {{expiresIn}} seconds.

+
+ +
+

Access token verified

+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/example/js/demo.js b/example/js/demo.js index c7cade6..bff202e 100644 --- a/example/js/demo.js +++ b/example/js/demo.js @@ -42,4 +42,48 @@ angular.module('demo', ['googleOauth']). alert("Failed to get token from popup."); }); }; + }); + +angular.module('demoRedirect', ['googleOauth']). + + config(function(TokenProvider) { + // Demo configuration for the "angular-oauth demo" project on Google. + // Log in at will! + + // Sorry about this way of getting a relative URL, powers that be. + var baseUrl = document.URL.replace('example/demo_redirect.html', ''); + + TokenProvider.extendConfig({ + clientId: '191261111313.apps.googleusercontent.com', + redirectUri: baseUrl + 'src/oauth2callback.html', // allow lunching demo from a mirror + scopes: ["https://www.googleapis.com/auth/userinfo.email"] + }); + }). + controller('DemoRedirectCtrl', function($scope, $window, $location, Token) { + + $scope.$on("$routeChangeStart", function () { + $scope.login(); + }); + + $scope.login = function() { + $scope.accessToken = Token.get(); + if ($scope.accessToken) { + // Success getting token. + // Verify the token before setting it, to avoid the confused deputy problem. + Token.verifyAsync($scope.accessToken). + then(function(data) { +// alert("verify token."); + $scope.accessTokenVerified = true; + }, function() { + alert("Failed to verify token."); + }); + } else { + Token.extendConfig({state: $location.absUrl()}); + var extraParams = {}; + Token.getTokenWithRedirect(extraParams); + } + } + + $scope.login(); + }); \ No newline at end of file diff --git a/src/js/angularOauth.js b/src/js/angularOauth.js index 7aef147..4bcba51 100644 --- a/src/js/angularOauth.js +++ b/src/js/angularOauth.js @@ -72,7 +72,8 @@ angular.module('angularOauth', []). response_type: RESPONSE_TYPE, client_id: config.clientId, redirect_uri: config.redirectUri, - scope: config.scopes.join(" ") + scope: config.scopes.join(" "), + state: config.state } }; @@ -184,6 +185,18 @@ angular.module('angularOauth', []). // TODO: reject deferred if the popup was closed without a message being delivered + maybe offer a timeout return deferred.promise; + }, + + extendConfig: function(configExtension) { + config = angular.extend(config, configExtension); + }, + + getTokenWithRedirect: function(extraParams) { + + var params = angular.extend(getParams(), extraParams), + url = config.authorizationEndpoint + '?' + objectToQueryString(params); + + $window.open(url, "_self"); } } } @@ -224,3 +237,47 @@ angular.module('angularOauth', []). window.opener.postMessage(params, "*"); window.close(); }); + + angular.module('angularOauthRedirect', ['angularOauth']).config(['TokenProvider', function (TokenProvider) { + + // can't find any other way to avoid exception if I want to be able to use Token.set inside RedirectCtrl + TokenProvider.extendConfig({ + clientId: 'test', + authorizationEndpoint: 'test', + redirectUri: 'test', + scopes: ['test'], + verifyFunc: 'test' + }); + + }]). + + controller('RedirectCtrl', function($scope, $location, $window, $log, Token) { + + /** + * TODO duplicate from CallbackCtrl + * + * Parses an escaped url query string into key-value pairs. + * + * (Copied from Angular.js in the AngularJS project.) + * + * @returns Object.<(string|boolean)> + */ + function parseKeyValue(/**string*/keyValue) { + var obj = {}, key_value, key; + angular.forEach((keyValue || "").split('&'), function(keyValue){ + if (keyValue) { + key_value = keyValue.split('='); + key = decodeURIComponent(key_value[0]); + obj[key] = angular.isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true; + } + }); + return obj; + } + + var queryString = $location.path().substring(1); // preceding slash omitted + var params = parseKeyValue(queryString); + + Token.set(params.access_token); + + $window.open(params.state, "_self"); + }); diff --git a/src/oauth2callback.html b/src/oauth2callback.html index 6c52618..e21f9ad 100644 --- a/src/oauth2callback.html +++ b/src/oauth2callback.html @@ -1,5 +1,5 @@ - + Receiving authentication