In a laravel 5.8 API project, I want users to login via their social accounts. So far I have been able to use Socialite to retrieve user info from the provider and use it to create a new user record. But when I try to have the user log in again, it throws up the following error
Call to undefined method Laravel\\Socialite\\Two\\User::createToken()
Here's the code I am working with
<?php
namespace App\Http\Controllers;
use App\User;
use Socialite;
use App\SocialAccount;
use App\Http\Resources\UserResource;
class SocialAuthController extends Controller
{
...
public function handleProviderCallback($provider)
{
$socialUser = Socialite::driver($provider)->stateless()->user();
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
/*
if account exist, return the social account user
else create the user account, then return the new user
*/
if ($userSocialAccount) {
// generate access token for use
$token = $socialUser->createToken('********')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($userSocialAccount))
]);
} else {
$user = User::create([
'firstname' => $socialUser->name,
'lastname' => $socialUser->name,
'username' => $socialUser->email,
'email_verified_at' => now()
]);
if ($user) {
SocialAccount::create([
'provider_id' => $socialUser->id,
'provider_name' => $provider,
'user_id' => $user->id
]);
}
// assign passport token to user
$token = $user->createToken('********')->accessToken;
return response()->json(['token' => $token, 'user' => new UserResource($user)]);
}
}
}
I haven't been able to spot the reason why I am getting the error when the user attempts a second login but there is no error if it's the first time the user logs in with a social account.
Why does it complain about Laravel\\Socialite\\Two\\User::createToken()
method? If I try adding this line use Laravel\\Socialite\\Two\\User
vscode intelephsense flags it as a duplicate of App\\User
so what is really going on in my code?
I think your last sentence hits the problem: the Laravel\\Socialite\\Two\\User
and App\\User
are two fully separate entities.
The Socialite::driver($provider)->stateless()->user()
provides you with a Socialite
User whereas User::create
creates an App\\User
.
The second $token = $user->createToken('********')->accessToken;
works because App\\User
has the createToken
function and the other does not.
First of all the problem I was having with having a token generated by passport for users authentication after the first social login was because I was calling the createToken
method on the user returned by Socialite
. As explained by @JorisJ1 Socialite
does not have the createToken
function so my initial code threw an error.
Here's how I fixed it
public function handleProviderCallback($provider)
{
// retrieve social user info
$socialUser = Socialite::driver($provider)->stateless()->user();
// check if social user provider record is stored
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
if ($userSocialAccount) {
// retrieve the user from users store
$user = User::find($userSocialAccount->user_id);
// assign access token to user
$token = $user->createToken('Pramopro')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($user))
]);
} else {
...
}
}
Comments are welcomed if there is a better way for adding social authentication to API.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.