Adnan Nuruddin
Adnan Nuruddin

Reputation: 41

Using laravel socialite and jwt-auth without session

Short version: What would be the appropriate way to send the JWT generated from Facebook login (laravel/socialite) to the angularjs front end without using session.

Long Version I am making an app that has angularjs front end and laravel 5.2 backend. I am using tymondesigns/jwt-auth for authentication instead of session.

I am also using laravel/socialite for social Facebook authentication. For that I am using the stateless feature of socialite so that I don't need session in any ways.

The basic authentication works perfectly. But, when I try to use Facebook login, I follow these steps

  1. User clicks on a button on the angular side that redirects to the provider login page of the back end.

public function redirectToProvider() { return Socialite::with('facebook')->stateless()->redirect(); } 2. User gives his login information. After logging in he is redirected to my handlecallback function.

        try {
        $provider = Socialite::with('facebook');

        if ($request->has('code')) {
            $user = $provider->stateless()->user();
        }

    } catch (Exception $e) {
        return redirect('auth/facebook');
    }

    return $this->findOrCreateUser($user);
  1. Next I use the findorcreate function to determine whether the user exists or not. If not than I just create a new user and create JWT from that.

        $user = User::where('social_id', '=', $facebookUser->id)->first();
    
    if (is_object($user)) {
        $token = JWTAuth::fromUser($user);
        return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular 
    } else {
        $result = array();
        $result['name'] = $facebookUser->user['first_name']
        $result['email'] = $facebookUser->user['email'];
        $result['social_id'] = $facebookUser->id;
        $result['avatar'] = $facebookUser->avatar;
        $result['gender'] = $facebookUser->user['gender'];
        $result['status'] = 'active';
        $result['login_type'] = 'facebook';
        $result['user_type'] = 'free_user';
    
        try {
            $user = User::create($result);
        } catch (Exception $e) {
            return response()->json(['error' => 'User already exists.'], HttpResponse::HTTP_CONFLICT);
        }
        $token = JWTAuth::fromUser($user);
        return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular
    }
    

My problem is, in the last block of code I am having to send the jwt to my frontend via url. Which isn't secure at all. What would be the right way to send the generated JWT to the frontend without using session. Thank you

Upvotes: 4

Views: 7561

Answers (3)

You can store token and use client side redirect without storing to browser history to redirect user to profile page without token in URL:

document.location.replace({profile-url})

Upvotes: 0

insign
insign

Reputation: 5803

The official documentation of Laravel Socialite says:

Stateless Authentication

The stateless method may be used to disable session state verification. This is useful when adding social authentication to an API:

return Socialite::driver('google')->stateless()->user();

Then, you can authenticate using the jwt-auth method:

JWTAuth::fromUser($user)

Upvotes: 4

jdforsythe
jdforsythe

Reputation: 1067

If you're using $http on the Angular side, try returning the token as a JSON response from Laravel:

return response()->json(compact('token'));

Then store the token in localStorage or sessionStorage or what have you.

If you're generating your Angular page from within Laravel (i.e. not using Laravel as an API, but showing your Angular page from /public/index.php, for instance) you could load the view with the token in the data for the view.

As long as you're using HTTPS either of these two scenarios are better than passing the token in the redirect URL.

Upvotes: 2

Related Questions