Shubham Raturi
Posted on February 14, 2024
Hi Everyone
To authenticate your app from the front end, follow these steps to build an API for Google login. The API will produce a bearer token, which you can check in the Laravel backend. and verify a user accordingly.
Step 1. Install Laravel Socialite package. and Laravel Passport
Step 2. Add this code to service.php
'google' => [
'api_key' => env('GOOGLE_API_KEY'),
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT')
]
setup the key form your google in your.env file
Step 3. Create a file in app/Grant/GoogleGrant.php
or anywhere in your app.
Step 4. Copy paste or modify this code according to you.
<?php
namespace App\Grants;
use App\User;
use DateInterval;
use Google\Exception;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Laravel\Socialite\Facades\Socialite;
use League\OAuth2\Server\Grant\AbstractGrant;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
class GoogleGrant extends AbstractGrant
{
public function __construct(
RefreshTokenRepositoryInterface $refreshTokenRepository
) {
$this->refreshTokenRepository = $refreshTokenRepository;
}
/**
* @inheritDoc
* @return string
*/
public function getIdentifier(): string
{
return 'google';
}
/**
* @inheritDoc
*
* @param ServerRequestInterface $request
* @param ResponseTypeInterface $responseType
* @param DateInterval $accessTokenTTL
* @return ResponseTypeInterface
* @throws
*/
public function respondToAccessTokenRequest(
ServerRequestInterface $request,
ResponseTypeInterface $responseType,
DateInterval $accessTokenTTL
): ResponseTypeInterface {
$client = $this->validateClient($request);
$scopes = $this->validateScopes($this->getRequestParameter('scope', $request));
$user = $this->validateUser($request);
// Finalize the requested scopes
$scopes = $this->scopeRepository
->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getAuthIdentifier());
// Issue and persist new tokens
$accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getAuthIdentifier(), $scopes);
$refreshToken = $this->issueRefreshToken($accessToken);
// Inject tokens into response
$responseType->setAccessToken($accessToken);
$responseType->setRefreshToken($refreshToken);
return $responseType;
}
/**
* Validate the request content and generate mapped user
*
* @param ServerRequestInterface $request
* @return User
* @throws GoogleLoginFailure
* @throws ValidationException
* @throws Exception
*/
public function validateUser(ServerRequestInterface $request): User
{
$validator = Validator::make($request->getParsedBody(), [
'access_token' => 'required'
]);
$validator->validate();
try {
$user = Socialite::driver('google')->userFromToken($request->getParsedBody()['access_token']);
} catch (ClientException $clientException) {
throw new ClientException($clientException);
}
/**
* @var $authUser User
*/
try {
return User::where('email', $user->email)->firstOrFail();
} catch (ModelNotFoundException $ex) {
abort(401, 'Custom message');
throw new ModelNotFoundException('custom message');
}
}
}
step 5. Register this grant you AuthServiceProvide.php file. inside boot()
method
try {
$this->app->make(AuthorizationServer::class)
->enableGrantType(
$this->googleGrant(),
Passport::tokensExpireIn()
);
} catch (LogicException $exception) {
return;
}
Step 6. Make a method AuthServiceProvide.php
/**
* Returns GoogleGrant instance
*
* @return GoogleGrant
* @throw
* @throws Exception
* @throws ContainerExceptionInterface
*/
protected function googleGrant(): GoogleGrant
{
$this->app->singleton(GoogleGrant::class, function () {
$googleGrant = new GoogleGrant($this->app->make(RefreshTokenRepository::class));
$googleGrant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());
return $googleGrant;
});
try {
return $this->app->get(GoogleGrant::class);
} catch (NotFoundExceptionInterface $e) {
throw new Exception($e);
}
}
💖 💪 🙅 🚩
Shubham Raturi
Posted on February 14, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.