renepardon / lighthouse-graphql-passport-auth
Add GraphQL types and mutations for login and recover password functionality through passport with lighthouse
Requires
- php: >=7.2
- ext-json: *
- guzzlehttp/guzzle: ^6.5
- laravel/passport: ^8.2
- laravel/socialite: ^4.3
- nuwave/lighthouse: ^4.8
Requires (Dev)
- orchestra/testbench: ^4.0
- phpunit/phpunit: ^8.0
Suggests
- guzzlehttp/guzzle: Send PSR7 requests
- laravel/passport: Authentication the easy way with OAuth2
- laravel/socialite: Social authentication
- nuwave/lighthouse: GraphQL with laravel
README
GraphQL mutations for Laravel Passport using Lighthouse version ^4.8
Installation
Make sure you have Laravel Passport installed.
To install run composer require renepardon/lighthouse-graphql-passport-auth
.
ServiceProvider will be attached automatically
Run this command to publish the migration, schema and configuration file
php artisan vendor:publish --provider="Renepardon\LighthouseGraphQLPassport\Providers\LighthouseGraphQLPassportServiceProvider"
Add the following env vars to your .env
PASSPORT_CLIENT_ID=
PASSPORT_CLIENT_SECRET=
You are done with the installation!
Configuration
In the configuration file you can now set the schema file to be used for the exported one like this:
/* |-------------------------------------------------------------------------- | GraphQL schema |-------------------------------------------------------------------------- | | File path of the GraphQL schema to be used, defaults to null so it uses | the default location | */ 'schema' => base_path('graphql/auth.graphql')
This will allow you to change the schema and resolvers if needed.
Usage
This will add 8 mutations to your GraphQL API
extend type Mutation { login(input: LoginInput): AuthPayload! refreshToken(input: RefreshTokenInput): RefreshTokenPayload! logout: LogoutResponse! forgotPassword(input: ForgotPasswordInput!): ForgotPasswordResponse! updateForgottenPassword(input: NewPasswordWithCodeInput): ForgotPasswordResponse! register(input: RegisterInput @spread): AuthPayload! socialLogin(input: SocialLoginInput! @spread): AuthPayload! verifyEmail(input: VerifyEmailInput! @spread): AuthPayload! }
- login: Will allow your clients to log in by using the password grant client.
- refreshToken: Will allow your clients to refresh a passport token by using the password grant client.
- logout: Will allow your clients to invalidate a passport token.
- forgotPassword: Will allow your clients to request the forgot password email.
- updateForgottenPassword: Will allow your clients to update the forgotten password from the email received.
- register: Will allow your clients to register a new user using the default Laravel registration fields
- socialLogin: Will allow your clients to log in using access token from social providers using socialite
- verifyEmail: Will allow your clients to verify the email after they receive a token in the email
Using the email verification
If you want to use the email verification feature that comes with laravel, please follow the instruction in the laravel documentation to configure the model in https://laravel.com/docs/6.x/verification, once that is done add the following traits
use Illuminate\Contracts\Auth\MustVerifyEmail; use Renepardon\LighthouseGraphQLPassport\HasLoggedInTokens; use Renepardon\LighthouseGraphQLPassport\MustVerifyEmailGraphQL; class User extends Authenticatable implements MustVerifyEmail { use Notifiable; use HasApiTokens; use HasSocialLogin; use MustVerifyEmailGraphQL; use HasLoggedInTokens; }
This will add some methods for the email notification to be sent with a token. Use the token in the following mutation.
{ mutation { verifyEmail(input: { "token": "HERE_THE_TOKEN" }) { access_token refresh_token user { id name email } } } }
If the token is valid the tokens will be issued.
Using socialite for social login
If you want to use the mutation for social login, please add the Renepardon\LighthouseGraphQLPassport\HasSocialLogin
trait to your user model like this
use Renepardon\LighthouseGraphQLPassport\HasSocialLogin; class User extends Authenticatable { use Notifiable; use HasApiTokens; use HasSocialLogin; }
This will add a method that is used by the mutation to get the user from the social network and create or get it from
the DB based on the provider
and provider_id
/** * @param Request $request * @return mixed */ public static function byOAuthToken(Request $request) { $userData = Socialite::driver($request->get('provider'))->userFromToken($request->get('token')); try { $user = static::where('provider', Str::lower($request->get('provider')))->where('provider_id', $userData->getId())->firstOrFail(); } catch (ModelNotFoundException $e) { $user = static::create([ 'name' => $userData->getName(), 'email' => $userData->getEmail(), 'provider' => $request->get('provider'), 'provider_id' => $userData->getId(), 'password' => Hash::make(Str::random(16)), 'avatar' => $userData->getAvatar() ]); } Auth::onceUsingId($user->id); return $user; }
You can override the method and add more fields if you need to.
Make sure Socialite is configured properly to use the social network, please see Laravel Socialite
Why the OAuth client is used in the backend and not from the client application?
When an application that needs to be re compiled and re deploy to stores like an iOS app needs to change the client for whatever reason, it becomes a blocker for QA or even brakes the production app if the client is removed. The app will not work until the new version with the updated keys is deployed. There are alternatives to store this configuration in the client but for this use case we are relying on the backend to be the OAuth client
Tests
To run the test in this package, navigate to the root folder of the project and run
composer install
Then
./vendor/bin/phpunit
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email rene dot pardon at boonweb dot de instead of using the issue tracker.
Credits
And all developers within the commit history.
License
The MIT License (MIT). Please see License File for more information.