Aug 31, 2024
0
Level 1
Laravel Socialite help
Please help.
I created OAuth for social networks through Laravel Socialite. Now I want to make sure that social networks can be linked to the main account in my application for convenient authorization. Tell me how to implement this?
Now done: Routes Controller Service SocialAccount Model
web.php
Route::group(['prefix' => 'v1', 'middleware' => ['session.start']], function () {
Route::group(['prefix' => 'oauth', 'middleware' => ['throttle.seconds']], function () {
Route::group(['prefix' => '{provider}', 'middleware' => ['oauth.provider_allowed']], function () {
Route::get('/', [OAuthController::class, 'redirect']);
Route::get('/callback', [OAuthController::class, 'handle']);
});
});
});
Controller
class OAuthController extends Controller
{
/**
* OAuthService instance.
*
* @var OAuthService
*/
protected OAuthService $service;
/**
* OAuthController constructor.
*
* @throws BindingResolutionException
*/
public function __construct()
{
$this->service = app()->make(OAuthService::class);
}
/**
* OAuth redirect.
*
* @param string $provider
* @return RedirectResponse
*/
public function redirect(string $provider): RedirectResponse
{
return Socialite::driver($provider)->stateless()->redirect();
}
/**
* Handle OAuth user.
*
* @param string $provider
*/
public function handle(string $provider)
{
return $this->service->handle(
providerUser: Socialite::driver($provider)->stateless()->user()
);
}
}
Service
class OAuthService extends AuthService
{
use Storagable;
/**
* Handle callback from OAuth provider.
*
* @param OAuthUser $providerUser
* @return array
*/
public function handle(OAuthUser $providerUser): array
{
if (empty($providerUser->email)) {
$providerUser->email = $this->setEmail($providerUser);
}
if ($user = $this->isRegistered($providerUser->email)) {
return $this->authenticate($user);
}
return $this->register([
'name' => $providerUser->name ?? $providerUser->nickname,
'email' => $providerUser->email,
'password' => $providerUser->email,
'image' => $this->storeByUrl($providerUser->getAvatar()),
'email_verified_at' => Carbon::now(),
]);
}
/**
* Generate custom email address.
*
* @param OAuthUser $user
* @return string
*/
protected function setEmail(OAuthUser $user): string
{
return $user->getId() . '@' . Config::get('oauth.email_domain');
}
/**
* Checking the existence of a user with this email address.
*
* @param string $email
* @return User|null
*/
private function isRegistered(string $email): ?User
{
return User::where('email', $email)->first();
}
/**
* Authenticate find User.
*
* @param User $user
* @return array
*/
protected function authenticate(User $user): array
{
return AuthResource::make([
'user' => $user->getVisibleFields(),
'access_token' => $this->createAccessToken($user),
])->resolve();
}
}
SocialAccount Model (for future)
class SocialAccount extends Model
{
/**
* Table name.
*
* @var string
*/
protected $table = 'auth_social_accounts';
/**
* Fillable.
*
* @var array
*/
protected $fillable = [
'user_id',
'provider',
'provider_user_id',
];
/**
* Casts.
*
* @var array
*/
protected $casts = [
'created_at' => 'timestamp',
'updated_at' => 'timestamp',
];
/**
* Get User.
*
* @return belongsTo
*/
public function user(): belongsTo
{
return $this->belongsTo(User::class);
}
}
Please or to participate in this conversation.