1

I'm developing a webapp with AngularJS as my framework and I want to implement OpenID for login, specifically with Google.

I was using the LightOpenID library for PHP and that seemed simple enough, but I'm struggling as to how to incorporate that into my app since it depends on the page redirecting to Google. I've considered three ways to approach this:

  1. A login.php at my base directory that users have to pass through
  2. A partial that iframes login.php
  3. login.php opening in a popup like http://openid-demo.appspot.com/

For the root solution (1), how do I go about passing state to the app?

The iframe solution (2) errors out on redirect IFRAME: Refused to display document because display forbidden by X-Frame-Options, which I suspect has to do with security on Google's end.

The popup solution (3) doesn't seem too great, as users have popup blockers, and popups on mobile aren't too satisfactory either.

Does anyone have any idea as to how I can work within the AngularJS framework/use JavaScript to sign users in with OpenID?

4

1 回答 1

2

You should be able to do (1) with a simple "logged in" session cookie, but that has problems as outlined here http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application.

(2) doesn't work as OpenID providers will bust out of any frames to prevent potential security problems.

Which leaves (3), which I got working by using https://github.com/witoldsz/angular-http-auth:

At my top level ngApp, I added the http-auth-interceptor dependency and added the following initializer function:

// main.js
app.run(function($rootScope, authService) {
    $rootScope.$on('event:auth-loginRequired', function() {
        window.open('/login.html');
    });
    $rootScope.loginConfirmed = function() {
        authService.loginConfirmed();
    };
});

When a json HTTP request returns a 401, the http-auth-interceptor will load login.html in a popup.

login.html is just a regular OpenID login form that eventually redirects to login_confirmed.html, which simply contains a <script> to close the popup and call the loginConfirmed function on the parent page:

<!-- login_confirmed.html -->
<script type="text/javascript">
    window.opener.loginConfirmed();
    window.close();
</script>

I don't know if there's a better way to call back into the angular app than this little glue function:

<!-- main.html -->
<script type="text/javascript">
    function loginConfirmed() {
        angular.element($('html')).scope().loginConfirmed();
    }
</script>

Anyway, pretty or not, it works.

于 2013-05-24T13:53:36.147 回答