From c6eb75a940b578cd6cac41dca86336da8c3e1f76 Mon Sep 17 00:00:00 2001 From: clakech <cyril.lakech@adeoservices.com> Date: Wed, 5 Jun 2013 11:50:17 +0200 Subject: [PATCH] add a feature to use redirect instead of popup -add a demo for this new feature warning: I reuse the same callback url because I don't have access to the config --- example/demo_redirect.html | 33 +++++++++++++++++++++ example/js/demo.js | 44 ++++++++++++++++++++++++++++ src/js/angularOauth.js | 59 +++++++++++++++++++++++++++++++++++++- src/oauth2callback.html | 2 +- 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 example/demo_redirect.html 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 @@ +<!doctype html> +<html lang="en" ng-app="demoRedirect" ng-controller="DemoRedirectCtrl"> +<head> + <meta charset="utf-8"> + <title>Client-side authentication demo with redirect</title> +</head> +<body> + +<div> + <div ng-show="accessToken" style="display: none"> + <h1>You're authenticated!</h1> + + <h2>Access token</h2> + <pre>{{accessToken}}</pre> + + <div ng-show="expiresIn"> + <h2>Expiry</h2> + <p>Expires in {{expiresIn}} seconds.</p> + </div> + + <div ng-show="accessTokenVerified"> + <h2>Access token verified</h2> + </div> + </div> +</div> + +<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.js"></script> + +<script src="js/demo.js"></script> +<script src="../src/js/googleOauth.js"></script> +<script src="../src/js/angularOauth.js"></script> +</body> +</html> \ 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 @@ <!doctype html> -<html lang="en" ng-app="angularOauth" ng-controller="CallbackCtrl"> +<html lang="en" ng-app="angularOauthRedirect" ng-controller="RedirectCtrl"> <head> <meta charset="utf-8"> <title>Receiving authentication</title>