4

I'm using Hello.js in my AngularJS application to let users authenticate with Facebook. Once the user is logged in and I get the user information from Facebook, I use the json and get the user object from my own database and store it in the root scope, so that various areas in my site can access the user's profile info (for example in the header where I display the logged in user's name).

Here's the service that handles the authentication stuff

angular.module('myApp')
  .factory('userService', function($rootScope, $location) {
    // Hello.js Functions
    hello.init({ 
      facebook : '1234567891234545'   
    });

    var service = {
      isLoggedIn: function() {
        return $rootScope.loggedInUser != null;
      },
      login: function() {
        hello('facebook').login( function() {
          hello('facebook').api('/me').success(function(json) {
            $rootScope.loggedInUser = getUserFromMyOwnAPI(json.id);    
            $rootScope.$apply(function() {
              $location.path('/');
            });
          });
        });          
      },
      logout: function() {
        hello('facebook').logout( function() {
          $rootScope.loggedInUser = null;
          $location.path('/');
        });          
      },
      loggedInUser: function(){
        return $rootScope.loggedInUser;
      }
    }

    return service;
})

The issue I'm having is that every time I refresh the page, I lose the profile info. Makes sense because $rootScope.loggedInUser which stores the user data (based on the json I got back from Facebook) would get reset after a page refresh.

How should I handle this? Should I be putting the user data in localStorage instead of the rootScope? Or should I somehow be leveraging hello('facebook').api('/me') each time I want to reference the user's profile info?

I noticed that hello.js already stores something in localStorage:

key: hello
{"facebook":{"state":"","access_token":"blahblahblah","expires_in":6776,"https":"1","client_id":"12345","network":"facebook","display":"none","redirect_uri":"http://adodson.com/hello.js/redirect.html","scope":"basic","expires":1412632794.806}}

So I 'm wondering if I would be duplicating the effort by adding the user object to localStorage.

Prabhu
  • 12,995
  • 33
  • 127
  • 210
  • 2
    What is your use-case? Do you anticipate a lot of page refreshes or are you building a single-page app? Do you need to maintain page state on a refresh or not? – DanArl Oct 09 '14 at 04:44
  • Agreed with Dan. Additionally, are you planning on supporting multiple login strategies (aside from Facebook)? –  Oct 09 '14 at 17:12
  • @DanArl It's a single page app. Not expecting a lot of page refreshes, but if they do refresh the page (or if they load the page in a new tab), I need to retain the user information. – Prabhu Oct 09 '14 at 21:55
  • @Prabhu do you have any feed back on my answer? – Aidin Oct 15 '14 at 19:53

3 Answers3

2

The answer to this question is subjective and could be argued different ways. However, based on your question and comment, my opinion is that retaining (non-sensitive) user profile information in local storage would be a good option to provide an uninterrupted user experience.

DanArl
  • 1,113
  • 8
  • 10
2

Never store the user information including but not limited social network info inside the localStorage, cookie, and/or other unsecured mechanisms. Even if you need to make a compromise on a not so critical information, then use memory (like scope variables). You also have to account for complexities arising on storing user info in localStorage such as when user logs out of the social network. Now, session tracking is as old of WWW itself. How to track the sessions? There are countless articles discussing the pro and cons of Cookies, Json Web Tokens, Session State in server side, etc. My personal opinion is to store the most of the user info in server side and link the current user to that session using a session ID stored in any possible medium like Cookie, Query Param, localStorage etc. Thats only useful if you have a backend and your OAuth provides you a token. I dont see anywhere in hello.js that it provides you a token. So given that you shouldnt store any client side user info in browser, and hello.js doesnt provide you with a token to reuse in subsequent calls my advice to you is to login the user every single time.

Aidin
  • 2,134
  • 22
  • 26
  • 1
    Never is not the correct word here. Some cases for example in android cordova applications, it is safe to store data into android filesystem that is private to this application's scope. There is still the case where you develop ultra secure military application and the customer loses his phone, stolen by mafia who hires a android and html5 guru who can then extract these sensitive personal informations from this dude's phone. lol. I should stop watching stupid action movies, and so do you. – Ant Oct 16 '14 at 01:49
  • getAuthResponse method does provide you token access token and you can do a silent login to refresh your token – Karthikeyan VK May 14 '17 at 13:56
0

about your code:

As Adin and DanArl already stated, you can implement the process of the user's session tracking in many different ways - preferably server side, identified via some kind of identifier stored in a session cookie.

Concerning your actual code, you may have a look at jshint: Three warnings

10  Use '!==' to compare with 'null'.
31  Missing semicolon.
34  Missing semicolon.
Three undefined variables
1   angular
4   hello
13  hello
14  hello
23  hello
15  getUserFromMyOwnAPI

You should inject 'hello' correctly, by passing 'hello' to your 'userService'. (have a look at: https://docs.angularjs.org/guide/di if you want more information about dependency injection in AngularJS)

about your actual problem:

After you have received the token - from your prefered way of storing it - you should be able to inspect and validate the token via:

GET graph.facebook.com/debug_token?
     input_token={token-to-inspect}
     &access_token={app-token-or-admin-token}

Source: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.1#checktoken

Then you may have a shot at passing this information to helljs (i'm used to this library)

Johannes Ferner
  • 718
  • 7
  • 15