Authentication
Enable Auth
- set
pepper.auth.disabled
tofalse
to enable authentication. - There should be a pepper class correspond to your defined user model. for example, if you have specified
App\Models\User::class
as your user model, you must haveApp\Pepper\User::class
class.
Authentication is done using JWT utilizing tymondesigns/jwt-auth package.
- update
.env
file to includeJWT_SECRET
secret (learn more):
php artisan jwt:secret
- Update you
User
model:
<?php
namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
- Configure Auth guard
in config/auth.php
make sure to set:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
- Enable authentication query and mutation in
config/pepper.php
:
...
'auth' => [
'disabled' => false
...
],
Login
{
login(
email: "amirmasoud@pepper.test"
password: "123456789"
) {
token
}
}
Return response would be JWT token if login credentials are valid; otherwise, it would be an authorization error.
Override login args
Add new method called setLoginArgs
to the defined User::class
class:
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
use GraphQL\Type\Definition\Type;
class User extends GraphQL
{
public function setLoginArgs(): array
{
return [
'email' => ['name' => 'email', 'type' => Type::string()],
'password' => ['name' => 'password', 'type' => Type::string()],
'other_field' => ['other_field' => 'name', 'type' => Type::string()],
];
}
}
Set username for login
The default args for login are email
and password
; however, you can change username by defining a method called setLoginUsernameField
in your pepper class, which corresponds to User::class
class:
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
class User extends GraphQL
{
public function setLoginUsernameField(): string
{
return 'username';
}
}
Register
mutation {
register(
name: "amirmasoud"
email: "amirmasoud@pepper.test"
password: "123456789"
password_confirmation: "123456789"
) {
token
}
}
Return response would be JWT token if no authorization error were raised.
Override Register Args
Add setRegisterArgs
method in Pepper User
class:
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
use GraphQL\Type\Definition\Type;
class User extends GraphQL
{
public function setRegisterArgs(): string
{
return [
'name' => ['name' => 'name', 'type' => Type::string()],
'email' => ['name' => 'email', 'type' => Type::string()],
'password' => ['name' => 'password', 'type' => Type::string()],
'password_confirmation' => ['name' => 'password_confirmation', 'type' => Type::string()],
];
}
}
Override Resolve Method
Add setRegisterResolve
method in Pepper User
class. $args
and $user
arguments
are available. The return of this method should be a user class instance.
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
use Illuminate\Support\Facades\Hash;
class User extends GraphQL
{
public function setRegisterResolve($args, $user)
{
return $user::create([
'name' => $args['name'],
'email' => $args['email'],
'password' => Hash::make($args['password']),
]);
}
}
Override Authorize Method
Add setRegisterAuthorize
method in Pepper User
class. the return of this method must be boolean.
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
class User extends GraphQL
{
public static function setRegisterAuthorize($root, $args, $ctx, $resolveInfo, $getSelectFields)
{
return true;
}
}
Override Authorization Message
Add setRegisterAuthorizationMessage
method in Pepper User
class. the return of this method must be a string.
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
class User extends GraphQL
{
public static function setRegisterAuthorizationMessage()
{
return 'Validation error';
}
}
Override Rules
Add setRegisterRules
method in Pepper User
class. the return of this method must be an array.
<?php
namespace App\Http\Pepper;
use Pepper\GraphQL;
class User extends GraphQL
{
public static function setRegisterRules()
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'confirmed'],
];
}
}
Forgot Password
Bt passing a registered user's email to the following GraphQL mutation you can send reset link to the user:
mutation {
forgot_password(email: "username@pepper.fake") {
status
}
}
You can customize the redirect link a user would ultimately recevice via a channel such as email, by setting the pepper.auth.frontend_url
and also can make further customization to the url by chaning the default value of the pepper.auth.password_reset
value. A default reset link would look likes as [defined_FRONTEND_URL_or_fallback_to_APP_URL]/[config_value_of_pepper_auth_password_reset]/?email=EMAIL&token=TOKEN
the query strings of email
and token
are filled automatically. A success message would look likes below:
{
"data": {
"forgot_password": {
"status": "We have emailed your password reset link!"
}
}
}
Or you might run into a error like below, which should be handles accordingly in your front-end application:
{
"errors": [
{
"message": "We can't find a user with that email address.",
"extensions": {
"category": "graphql"
},
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"forgot_password"
]
}
],
"data": {
"forgot_password": null
}
}
Reset Password
After requesting forgot password mutation you can invoke following GraphQL mutation to reset a user's password. It requires that you have properly handled frontend_url
and password_reset
in Pepper configuration.
mutation {
reset_password(
email: "amirmasoud@pepper.fake",
token: "token_from_sent_email_in_forgot_password",
password: "new_secret",
password_confirmation: "new_secret"
)
}
A success reset password can look like below:
{
"data": {
"forgot_password": {
"status": "success localized reset password message."
}
}
}