Search code examples
angularjslaravelfacebook-php-sdkaccess-tokenfacebook-access-token

Integrating Laravel, Facebook and Angular with token-based-authentication


My use case:

User is already logged in automatically server side using Facebook with laravel and Socialite.

I check if the user exists in the db and if not create it and log them into laravel.

Then I need to start an Angular app and make sure they are logged in with Laravel / Facebook.

After reading this article, it looks like this token based approach is what I should take.

In the tutorial you serve a login form with Angular, and then pass the email and password to an authenticate controller (Laravel), which returns a token (create by JWT-Auth).

Once the token is in Angular all is well, my problem is that I want to get the token directly into Angular without a login form since the user is already logged in as mention above.

I'm wondering if I could just output the token in markup somewhere and then pick it up from Angular or would that somehow be a security risk? I guess people will only be able to view source and see their own token?

If this is the wrong way to do this, then how should I do it? Do I need to authenticate with Facebook with Javascript, and then create a new laravel user with ajax?

Thanks so much!


Solution

  • One approach you could take is to add something to your .config block that checks for the presence of a JWT in local storage and if there isn't one there, makes a request to the API to see if the user is logged in on the Laravel side. If the user is logged in, a JWT is returned which can be picked up and saved in local storage. Since the .config block is run when the Angular app loads, this will only happen once, which is probably what you're looking for.

    Here's what that might look like. First the Laravel side:

    // AuthenticateController.php
    
    ...
    // Simulates a user being logged in on the Laravel side through something
    // other than credentials sent from the front-end. Obviously you would use
    // Socialite
    
    public function authenticate()
    {
        $user = User::find(1);
        $token = JWTAuth::fromUser(1);
        return response()->json(compact('token'));
    }
    ...
    

    Then the Angular:

    // app.js
    
    ...
    .run(function($rootScope, $state, $auth) {
        if(!$auth.isAuthenticated()) {
    
            // No credentials provided because the user is already logged in on the server
            $auth.login().then(function() {
                $state.go('users');
            }
        }
    
        $rootScope.$on('$stateChangeStart', function(event, toState) {
    ...
    

    This would just run when the Angular app loads, which will be after your user has logged in with Socialite. It's essentially just checking whether there is a user logged in on the back end and if so, the token is retrieved. It's a bit hacky and the interface isn't obvious, so it might not be the best solution.

    You would need to arrange your authenticate controller on the Laravel side such that it returns the token if the user has logged in via socialite or require credentials if he/she hasn't (which is the traditional login).

    You could also look at this approach to see if it works for you: https://github.com/barooney/jot-bot/tree/socialite

    Let me know if that works out!