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);
}
}
Top comments (0)