DEV Community

Cover image for GraphQL Auth with Passport and Lighthouse PHP
Jose Luis Fonseca
Jose Luis Fonseca

Posted on • Edited on • Originally published at lighthouse-php-auth.com

GraphQL Auth with Passport and Lighthouse PHP

Writing a GraphQL API with Lighthouse PHP and Laravel is really fun, but something that you always have to do is add authentication. This is a common task that Laravel already covers with Passport, but what if you want to have your login and refresh token endpoints as mutations? That is actually a good idea since you don’t really have to document your authentication mechanisms apart from your GraphQL API. You can have it with mutations as well. This is what inspired me to write a little package called Lighthouse GraphQL Passport Auth which at first seems like a long name and to tell you the truth, it is. But let’s dive into how to use it and we worry about the name later XD.

Installation and configuration

First thing we need to do is install the package, now please keep in mind that Lighthouse PHP is required as well as passport, so why don’t we install it in one shot? In a brand new laravel app please enter:

composer require nuwave/lighthouse laravel/passport joselfonseca/lighthouse-graphql-passport-auth
Enter fullscreen mode Exit fullscreen mode

Now let’s configure each of the packages starting with Laravel Passport, for that we are going to first run the migrations.

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Then we should run the passport Install command.

php artisan passport:install
Enter fullscreen mode Exit fullscreen mode

Then add the HasApiTokens trait to your user model


namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}
Enter fullscreen mode Exit fullscreen mode

Now we should register the passport routes as we still need them to be able to get tokens internally.

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
    }
}
Enter fullscreen mode Exit fullscreen mode

Once we have this let’s add the passport driver to the API guard in the config/auth.php file.

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
Enter fullscreen mode Exit fullscreen mode

This should conclude the passport configuration.

Now let’s configure and install the Lighthouse PHP package. since it was already pulled from composer we just need to run the following commands to publish the default schema.

php artisan vendor:publish --tag=lighthouse-schema
Enter fullscreen mode Exit fullscreen mode

This command will create a file in graphql/schema.graphql with the following schema

"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-01-01 13:00:00`."
scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")

"A date string with format `Y-m-d`, e.g. `2011-05-23`."
scalar Date @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date")

type Query {
    users: [User!]! @paginate(type: "paginator" model: "App\\User")
    user(id: ID @eq): User @find(model: "App\\User")
}
type User {
    id: ID!
    name: String!
    email: String!
    created_at: DateTime!
    updated_at: DateTime!
}
Enter fullscreen mode Exit fullscreen mode

If you have this file you should be ready to continue with the Lighthouse GraphQL Passport Auth package.

To get the values you need to open your database client and grab the password oauth client from the oauth_clients table, get the client id and secret and put them in the .env file

PASSPORT_CLIENT_ID=2
PASSPORT_CLIENT_SECRET=69YJomGV9plchWIkGD2PyKBBTHfkNA7H83iYGc6j
Enter fullscreen mode Exit fullscreen mode

Once you do that, publish the package configuration and default schema.

php artisan vendor:publish --provider="Joselfonseca\LighthouseGraphQLPassport\Providers\LighthouseGraphQLPassportServiceProvider"
Enter fullscreen mode Exit fullscreen mode

This command should publish 2 files, the config/lighthouse-graphql-passport.php and graphql/auth.graphql file. For convenience and to be able to have better control over the auth schema lets update the config file to use the published schema by changing the value for the schema property to the path to the published file like this:

'schema' => base_path('graphql/auth.graphql')
Enter fullscreen mode Exit fullscreen mode

This will allow us to manipulate the schema if we need to extend it or make changes to the resolvers.

Now let’s remove the user type from the auth schema since we already have it in the default one exported before. Go to the graphql/auth/graphql file and remove the following type

type User {
    id: ID!
    name: String!
    email: String!
}
Enter fullscreen mode Exit fullscreen mode

Once we do that, we need to add a default mutation to the schema so the auth can extend it or we can simply move the auth mutations to the Mutation type in the main schema file. So look for this code in the graphql/auth.graphql file and move it to graphql/schema.graphql file

extend type Mutation {
    login(input: LoginInput @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Login@resolve")
    refreshToken(input: RefreshTokenInput @spread): RefreshTokenPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\RefreshToken@resolve")
    logout: LogoutResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Logout@resolve")
    forgotPassword(input: ForgotPasswordInput! @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ForgotPassword@resolve")
    updateForgottenPassword(input: NewPasswordWithCodeInput @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ResetPassword@resolve")
    register(input: RegisterInput @spread): RegisterResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Register@resolve")
    socialLogin(input: SocialLoginInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\SocialLogin@resolve")
    verifyEmail(input: VerifyEmailInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\VerifyEmail@resolve")
    updatePassword(input: UpdatePassword! @spread): UpdatePasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\UpdatePassword@resolve") @guard(with: ["api"])
}
Enter fullscreen mode Exit fullscreen mode

Then remove the extend word

type Mutation {
    login(input: LoginInput @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Login@resolve")
    refreshToken(input: RefreshTokenInput @spread): RefreshTokenPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\RefreshToken@resolve")
    logout: LogoutResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Logout@resolve")
    forgotPassword(input: ForgotPasswordInput! @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ForgotPassword@resolve")
    updateForgottenPassword(input: NewPasswordWithCodeInput @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ResetPassword@resolve")
    register(input: RegisterInput @spread): RegisterResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Register@resolve")
    socialLogin(input: SocialLoginInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\SocialLogin@resolve")
    verifyEmail(input: VerifyEmailInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\VerifyEmail@resolve")
    updatePassword(input: UpdatePassword! @spread): UpdatePasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\UpdatePassword@resolve") @guard(with: ["api"])
}
Enter fullscreen mode Exit fullscreen mode

You should now have your schema files like this

graphql/auth.graphql

input LoginInput {
    username: String!
    password: String!
}

input RefreshTokenInput {
    refresh_token: String
}

type User {
    id: ID!
    name: String!
    email: String!
}

type AuthPayload {
    access_token: String
    refresh_token: String
    expires_in: Int
    token_type: String
    user: User
}

type RefreshTokenPayload {
    access_token: String!
    refresh_token: String!
    expires_in: Int!
    token_type: String!
}

type LogoutResponse {
    status: String!
    message: String
}

type ForgotPasswordResponse {
    status: String!
    message: String
}

type RegisterResponse {
    tokens: AuthPayload
    status: RegisterStatuses!
}

type UpdatePasswordResponse {
    status: String!
    message: String
}

enum RegisterStatuses {
    MUST_VERIFY_EMAIL
    SUCCESS
}

input ForgotPasswordInput {
    email: String! @rules(apply: ["required", "email"])
}

input NewPasswordWithCodeInput {
    email: String! @rules(apply: ["required", "email"])
    token: String! @rules(apply: ["required", "string"])
    password: String! @rules(apply: ["required", "confirmed", "min:8"])
    password_confirmation: String!
}

input RegisterInput {
    name: String! @rules(apply: ["required", "string"])
    email: String! @rules(apply: ["required", "email", "unique:users,email"])
    password: String! @rules(apply: ["required", "confirmed", "min:8"])
    password_confirmation: String!
}

input SocialLoginInput {
    provider: String! @rules(apply: ["required"])
    token: String! @rules(apply: ["required"])
}

input VerifyEmailInput {
    token: String!
}

input UpdatePassword {
    old_password: String!
    password: String! @rules(apply: ["required", "confirmed", "min:8"])
    password_confirmation: String!
}
Enter fullscreen mode Exit fullscreen mode

graphql/schema.graphql

"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-01-01 13:00:00`."
scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")
"A date string with format `Y-m-d`, e.g. `2011-05-23`."
scalar Date @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date")

type Query {
    users: [User!]! @paginate(type: "paginator" model: "App\\User")
    user(id: ID @eq): User @find(model: "App\\User")
}

type Mutation {
    login(input: LoginInput @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Login@resolve")
    refreshToken(input: RefreshTokenInput @spread): RefreshTokenPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\RefreshToken@resolve")
    logout: LogoutResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Logout@resolve")
    forgotPassword(input: ForgotPasswordInput! @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ForgotPassword@resolve")
    updateForgottenPassword(input: NewPasswordWithCodeInput @spread): ForgotPasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\ResetPassword@resolve")
    register(input: RegisterInput @spread): RegisterResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\Register@resolve")
    socialLogin(input: SocialLoginInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\SocialLogin@resolve")
    verifyEmail(input: VerifyEmailInput! @spread): AuthPayload! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\VerifyEmail@resolve")
    updatePassword(input: UpdatePassword! @spread): UpdatePasswordResponse! @field(resolver: "Joselfonseca\\LighthouseGraphQLPassport\\GraphQL\\Mutations\\UpdatePassword@resolve") @guard(with: ["api"])
}

type User {
    id: ID!
    name: String!
    email: String!
    created_at: DateTime!
    updated_at: DateTime!
}
Enter fullscreen mode Exit fullscreen mode

Lastly we need to install the GraphQL playground we will use to send queries and mutations to our GraphQL server, for that run the following command

composer require mll-lab/laravel-graphql-playground
Enter fullscreen mode Exit fullscreen mode

This is ready for tenting now!

Testing the auth mutations

Let’s start by running the PHP dev server

php artisan serve
Enter fullscreen mode Exit fullscreen mode

This will open the port 8000 in our localhost for us to run the project, let’s navigate to http://127.0.0.1:8000/graphql-playground and you should see the playground like this

Now let’s create a user using a simple console command so we can log in using our graphql API. In the routes/console.php file enter

Artisan::command('user', function () {
    \App\User::create([
        'name' => 'Jose Fonseca',
        'email' => 'myemail@email.com',
        'password' => bcrypt('123456789qq')
    ]);
})->describe('Create sample user');
Enter fullscreen mode Exit fullscreen mode

Then run the command in the console

php artisan user
Enter fullscreen mode Exit fullscreen mode

Now that we have a user to test with, lets run the following mutation in the GraphQL Playground

mutation {
  login(input: {
    username: "myemail@email.com",
    password: "123456789qq"
  }) {
    access_token
    refresh_token
    expires_in
    token_type
    user {
      id
      email
      name
      created_at
      updated_at
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This should give you the following response

{
  "data": {
    "login": {
      "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijk3NDE3MTI1YjBmNjQyZDNkZDljMDkwOGJiNTM2NDQ5YTYwZWU5ZTQ0ZTBkYzEzY2E5M2FhNGFjODI5ZWRiNzkwMWZhZmY5NzVhZTc5MjRiIn0.eyJhdWQiOiIyIiwianRpIjoiOTc0MTcxMjViMGY2NDJkM2RkOWMwOTA4YmI1MzY0NDlhNjBlZTllNDRlMGRjMTNjYTkzYWE0YWM4MjllZGI3OTAxZmFmZjk3NWFlNzkyNGIiLCJpYXQiOjE1NjE0MDkyMDMsIm5iZiI6MTU2MTQwOTIwMywiZXhwIjoxNTkzMDMxNjAzLCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.CZOpXN0mFHXAQexpA4-FPMOcV-bdZRJD7zUK7guzethg9KUMrALhzgwfQZJv3w74Gnj54aAbdswHBwZEt9DREyEer7Ht0c8108amOllPqb-ydLET1RL1oYCE9H9vvUK0ZafLp09pMrXKot6UcViGOy97KF7YilAvaFfyGxSOmTTZyn0noe9F2ztIOPd3u9XuPuTR5yL-NqHufTTtyJkdQ2xPo03bF4tRfpMXQ5prnIJi4rxmBkpASwMwVraL4lVSZg_9STWMxXWWFdvmXydkNUtQSAftQyHmwMy33OOTxRtFRDN_1Y9wW7U9okVRM-gindkx0o_EB7ekcP1mvHc2PwxwWPMfFxezex98wYX3jTo8y7CN4vDrgUdXqrKkFc6JzwBgn8q_f7c5SzbzxR824h6ujFzSgMaUk_8zKtHX_qgDqaqPVzTebazQ0Pu9PNoYcCkQi5bNldCGuuaMsMxz3H-CWstR4_pAj9_jeKdvC5MA0OkQ30b3RlSmhSqb65LfZEU-y3wG62FKHD49JxBOpPh_Ga8SOQvfOCIL3SzURX9uOvSgcprQqLBYkhJNJC0gobAFgrKHbDhrBVvGH5U4BbIPVX-gnhR44aoyIf8sXFJQkPJJ7-p8HrCqDqjahrlDXsf4DRZGaVJJFhX2VcWAkCcQA2yJ1LSS1XpNU5oL-x4",
      "refresh_token": "def502004531ba2a174546464239e59c3d07332f8aec44bf95db59ba578bcb58c1986dd494d887c79282daf7379d2959b35816e07245ad237e5fa5e6b3ea1ff19ca0058aa82abc4d0abad427eb045b894c7591e4e248d684ea0c6772011ac1723d3d63805e0e148ec0875277072e39d9ecafcbe55d29b28607dc3ea9f85bdc0ca88aadca41b97e8f061b9b326dc922708f6826aee7e2e3296891e923fd9b5386b4c99d46e9832cb8e191c63bb31394a3dc92a8fc1b907925e9c1888d8b0c4d8c30ea330785dd429623e93979670856fdb5bf80c6c8cac08dc7d040d796e535aa082e241dd38b4ab7a4b0055d554cd85888533c76af594bed20dddcded751bfecd0ffdb741169f204c732cef0e2c49c26ec81de9dd8099b5ab1a481283f70c9685a11ca7018c259688601359722aee0f527c95b8b48062be81d414ce3e10a334d8b5c4f64c25b248c0b76bc40596b99580e38310e7d3a4e82c910276645101d821f",
      "expires_in": 31622400,
      "token_type": "Bearer",
      "user": {
        "id": "1",
        "email": "myemail@email.com",
        "name": "Jose Fonseca",
        "created_at": "2019-06-24 20:43:53",
        "updated_at": "2019-06-24 20:43:53"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That is IT! you can now use the token in your GraphQL API!

Testing a protected query

Let’s modify the users query to require authentication with passport, for that open the graphql/schema.graphql file and update the users query with the following

users: [User!]! @guard(with: ["api"]) @paginate(type: "paginator" model: "App\\User")
Enter fullscreen mode Exit fullscreen mode

Now try to run the a users query

{
  users(count: 20){
    data {
      id
      email
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This should give you an authentication error like the following

{
  "errors": [
    {
      "debugMessage": "Unauthenticated.",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "users"
      ],
      "trace": [
...
}
Enter fullscreen mode Exit fullscreen mode

This means the query needs to have the access token in the request. To do that in the GraphQL Playground add the authorization header with the token we generated before

Re run the query and you should have the result just fine!

As you can see the query is protected and you can now use authentication in your GraphQL API.

Now go a head and try the rest of the mutations available to like refresh the token or reset a password.

If you like this little package please start it in Github and let me know if you run into any issues.

GitHub logo joselfonseca / lighthouse-graphql-passport-auth

Add GraphQL mutations to get tokens from passport for https://lighthouse-php.com/

Lighthouse GraphQL Passport Auth (Laravel ^7.0 / Lighthouse ^4.0)

Total Downloads StyleCI License

GraphQL mutations for Laravel Passport using Lighthouse PHP.

Tutorial

You can see this tutorial for installation and usage.

Documentation

Find the detailed documentation in the documentation site

Change log

Please see the releases page https://github.com/joselfonseca/lighthouse-graphql-passport-auth/releases

Tests

To run the test in this package, navigate to the root folder of the project and run

    composer install
Enter fullscreen mode Exit fullscreen mode

Then

    vendor/bin/phpunit
Enter fullscreen mode Exit fullscreen mode

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email jose at ditecnologia dot com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.




Happy Coding!

Latest comments (84)

Collapse
 
haronur profile image
Haron

mutation {
logout {
status
message
}
}
Dose not works
it throws
{
"errors": [
{
"message": "Not Authenticated",
"extensions": {
"reason": "Not Authenticated",
"category": "authentication"
},
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"logout"
],
}

Collapse
 
haronur profile image
Haron

Can we get the rest of the mutations Example like:
mutation {
logout {
status
message
}
}
and
mutation {
forgotPassword(input: {
email: "haronur@email.com"
}) {
status
message
}
}
and so on

Collapse
 
haronur profile image
Haron • Edited

Can we get the rest of the mutations Example like:
mutation {
logout {
status
message
}
}
and
mutation {
forgotPassword(input: {
email: "haronur@email.com"
}) {
status
message
}
}
and so on

Collapse
 
houston2204 profile image
MAX RAMIREZ

Hola, y como es que se podría aplicar varios middlewares quiero usar un middleware para hacer multitenants.

Collapse
 
joselfonseca profile image
Jose Luis Fonseca

en la configuración de Lighthouse se definen los middleware que pasan por todo el request
github.com/nuwave/lighthouse/blob/...
O puede crear custom directives
lighthouse-php.com/5.3/custom-dire...

Collapse
 
madrobotno profile image
MAD Robot (Martin Agnar Dahl)

Hey Jose!
I am trying to install Your package but I receiving error message:
"
Problem 1
- joselfonseca/lighthouse-graphql-passport-auth[5.1.0, ..., 5.1.1] require laravel/passport ^10.0 -> found laravel/passport[v10.0.0, v10.0.1, 10.x-dev] but it conflicts with your root composer.json require (~9.0).
- Root composer.json requires joselfonseca/lighthouse-graphql-passport-auth ^5.1 -> satisfiable by joselfonseca/lighthouse-graphql-passport-auth[5.1.0, 5.1.1].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
"
I use laravel 7.24

Collapse
 
joselfonseca profile image
Jose Luis Fonseca

That is because it requires passport 10 and you are requiring 9, can you update to passport 10? it should fix the issue.

Collapse
 
redefinered profile image
Red De Guzman • Edited

Hey man, hows it going? This is nice. I'm trying to implement this. But I think the instructions are outdated at the moment?

Collapse
 
joselfonseca profile image
Jose Luis Fonseca

Not sure what you mean by that, are you facing any errors? Remember this is for a PHP Laravel app or API, if you are looking for something more like a service I would recommend you do hasura.io/ or prisma.io/

Collapse
 
redefinered profile image
Red De Guzman

there are compatibility errors when I generate a new laravel app and run the very first terminal command composer require nuwave/lighthouse laravel/passport joselfonseca/lighthouse-graphql-passport-auth

Thread Thread
 
redefinered profile image
Red De Guzman

I think that these instructions are only applicable to Laravel 7.* ?

Thread Thread
 
joselfonseca profile image
Jose Luis Fonseca • Edited

If you are on Laravel 8 then I don't yet have a compatible version. I am working on that.

Collapse
 
georgebarlow profile image
George Barlow

Hiya, I'm trying to use this in an app and trying to check whether the users credentials were incorrect. I tried to enter some dummy data into the email and password field and got this response:
When using this mutation:

mutation {
login(input: { username: "dave@something.uk", password: "1431531" }) {
access_token
refresh_token
expires_in
token_type
}
}

I got this:

{
"errors": [
{
"message": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.",
"extensions": {
"guards": [],
"category": "authentication"
},

Any reason why?

Collapse
 
ramirezfer772 profile image
ramirezfer772 • Edited

Hola, una duda, quiero marcar los emails como verificado y estoy tratando de usar tu mutation VerifyEmail, me pide que inserte un token como argumento,
hasta ahorita tengo algo como esto cuando mande el link al correo del usuario usando $user->sendEmailVerificationNotification()

"example.com/email/verify/10/b2cce7e16059b006a97cb2a2e2fcde1cafeb7bc5?expires=1592270169&signature=b9a248271a992f36d5097b2a2683982a882ebfdbbb0546d447059c9b012b7cc0"

como obtengo tal token?
Gracias te agradesco

Collapse
 
ramirezfer772 profile image
ramirezfer772

Encontre una solución para verificar el email, la dejo aquí por si le sirve a alguien en el futuro:
1.crear un mutation VerifyEMail.php con este codigo:
public function __invoke($rootValue, array $args, GraphQLContext $context, ResolveInfo $resolveInfo)
{

    $email = $args['email'];
    $requestHash = $args['requestHash'];
    $requestID = $args['requestID'];

    $user = User::where('email', $email)->first();

    if (! hash_equals((string) $requestID, (string) $user->getKey())) {
        throw new AuthorizationException;
    }

    if (! hash_equals((string) $requestHash, sha1($user->getEmailForVerification()))) {
        throw new AuthorizationException;
    }

    if ($user->markEmailAsVerified()) {
        event(new Verified($user));

        return $user;
    }

}

2.testear:
mutation {
VerifyEMail(
email:"example@gmail.com"
requestID: 10
requestHash: "b2cce7e16059b006a97cb2a2e2fcde1cafeb7bc5"
) {
id
}
}

  1. en web.php:

Route::get('email/verify/{id}/{hash}', function () {
return view('welcome');
})->name('verification.verify')

4.desde la vista mandar el email que el usuario escribió, mandar la id y el hash

Ojala sirva.

Collapse
 
santiagoloperam profile image
Don Santi

Hola Jose, si yo quisiera usar el email y un username secreto para logueo (tipo bancolombia), que archivos debo afectar aparte del auth.graphql? Gracias hermano por esta iniciativa con Graphql

Collapse
 
joselfonseca profile image
Jose Luis Fonseca

puedes editar el input y usar el metodo findForPassport en el user model

laravel.com/docs/7.x/passport#cust...

Collapse
 
santiagoloperam profile image
Don Santi

José disculpa en register me sale este error despues de poner user_name como credencial pero si me registra. Donde más se podría configurar ese campo user_name para que me devuelva que si registró?

Thread Thread
 
santiagoloperam profile image
Don Santi

Jose disculpa te pregunto de nuevo. Con la credencial user_name me funciona en login cambiando el modelo como dices:
public function findForPassport($username)
{
return $this->where('user_name', $user_name)->first();
}
pero la mutación register funciona y devuelve error, es decir registra en la BD pero me devuelve esto:

"errors": [
{
"message": "Authentication exception",
"extensions": {
"reason": "Incorrect username or password",
"category": "authentication"
},
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"register"
],
"trace": [
{
"file": "C:\conjuntos laravel\horizontal_lighthouse\vendor\joselfonseca\lighthouse-graphql-passport-auth\src\GraphQL\Mutations\Register.php",
"line": 45,
"call": "Joselfonseca\LighthouseGraphQLPassport\GraphQL\Mutations\BaseAuthResolver::makeRequest(array(5))"

Thread Thread
 
joselfonseca profile image
Jose Luis Fonseca

tambien hay que configurarlo en la config del paquete

config('lighthouse-graphql-passport.username')

Collapse
 
masterawss profile image
masterawss

Hola, esta librería me parece genial, pero tengo una duda. Cómo puedo hacer para iniciar sesión con el ID del usuario; algo como usar Auth::login($user);

Tengo entendido que puedes hacer tu propio resolver, pero es necesario que deba returnar access_token, refresh_token, expire_in para que pueda guardarlo desde el frontend o hay otra manera ?

Talvez me estoy acomplejando por la falta de conocimiento, pero alguien me podría ayudar a aclarar eso por favor ?

Collapse
 
joselfonseca profile image
Jose Luis Fonseca

Esta librería esta pensada para usar Passport laravel.com/docs/7.x/passport yes solo un puente para el mismo, o sea que si usas los tokens, Si no necesitas este tipo de authentication puedes solo usar laravel o otros métodos.