loading...
Cover image for Handling user registration and authentication on a laravel API using jwt

Handling user registration and authentication on a laravel API using jwt

tngeene profile image Ted Ngeene Updated on ・6 min read

CRUD API with laravel and JWT (2 Part Series)

1) Handling user registration and authentication on a laravel API using jwt 2) How to create an API with laravel resources

This series is going to cover how to build a REST API using laravel API resources, the first part of the series will include setting up the project and handling user authentication using JSON web tokens(JWTs). The second part I'll be building a book review API with the API resources and in the third part, I will test the API with postman.
Before I begin, I'm going to assume the following:

  1. knowledge of PHP.
  2. Basic knowledge of laravel.
  3. Have composer and laravel installed.
  4. Have postman installed.

The entire source code for this application can be found on my github

let's dive in.

Creating the application

The first thing we're going to do is create a new laravel app
you can do this either by

laravel new bookreview

or

composer create-project laravel/laravel bookreview

if you do not have the installer you can get it by running

composer global require laravel/installer

note: At the time of writing this post, we're going to be using laravel 6.0 but it applies for any laravel version from 5.5

for more information on how to install laravel you can check their official documentation
Now that we have laravel installed and the project set up, let us get started on using jwt.

what are JWTs?

JSON Web Token (JWT) is an Internet standard for creating JSON-based access tokens that assert some number of claims. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client. The client could then use that token to prove that it is logged in as admin. The tokens are signed by one party's private key (usually the server's), so that both parties can verify that the token is legitimate. The tokens are designed to be compact, URL-safe, and usable especially in a web-browser single-sign-on (SSO) context. JWT claims can be typically used to pass the identity of authenticated users between an identity provider and a service provider.

Getting started

Navigate to the project's directory and install the third party package called jwt-auth by running

composer require tymon/jwt-auth "1.0.*"

Once the package has installed, we'll need to publish the vendor's files by running

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

you should be able to see the package in the vendor folders if the command runs successfully.
Next we will generate a jwt secret key by running

php artisan jwt:secret

Open the .env file in your project and you will see a randomly generated secret key for your application.
Next, we will need to make our user model implement JWT. By default, laravel comes with a user model, so we will run any commands to create one.
open the app/user.php file and update it to look like the following:

<?php

namespace App;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    public function getJWTCustomClaims()
    {
        return [];
    }
 }

We defined two methods to return the JWTIdentifier and JWTCustomClaims. Custom claims are used in generating the JWT token. For this guide, we will not be using custom claims.
Next, let's configure auth guard to make use of the jwt guard by editing the config/auth.php to look like this

'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],
 ...
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => True,
        ],
    ],

Here we are setting the api guard as the default and telling the api guard to use jwt.
That concludes the installation of jwt, let's continue to the rest of the application.

Set up the Database

For this guide, we're going to be using MySQL database, I am using xampp as my database.
open the .env file and edit the database settings to look like this

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=bookreview
DB_USERNAME=root
DB_PASSWORD=

Also, do remember to create the database "bookreview" on the localhost/phpmyadmin
Turn the local laravel server on by running php artisan serve and turning xampp or whichever database you have.
we will not modify anything on the default user's table migration. Next, run the migrations by php artisan migrate command.

Making the User Controller

We will make a controller to handle the registration and login of users. We'll call this controller, AuthController
Run the command php artisan make:controller AuthController
Once the controller is created, navigate to App\Http\Controllers\AuthController.php file and modify it to look like this...

<?php

namespace App\Http\Controllers;


use Illuminate\Http\Request;
use App\User;

class AuthController extends Controller
{
    public $loginAfterSignUp = true;

    public function register(Request $request)
    {
      $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => bcrypt($request->password),
      ]);

      $token = auth()->login($user);

      return $this->respondWithToken($token);
    }

    public function login(Request $request)
    {
      $credentials = $request->only(['email', 'password']);

      if (!$token = auth()->attempt($credentials)) {
        return response()->json(['error' => 'Unauthorized'], 401);
      }

      return $this->respondWithToken($token);
    }
    public function getAuthUser(Request $request)
    {
        return response()->json(auth()->user());
    }
    public function logout()
    {
        auth()->logout();
        return response()->json(['message'=>'Successfully logged out']);
    }
    protected function respondWithToken($token)
    {
      return response()->json([
        'access_token' => $token,
        'token_type' => 'bearer',
        'expires_in' => auth()->factory()->getTTL() * 60
      ]);
    }

}

The register function requires the user to provide their name, email and password. While the login function requires one to only provide the email and password. Both methods return a response with a JWT by calling a respondWithToken() method which gets the token array structure. Users will have to login after registration hence the

public $loginAfterSignUp = true;

The token expires after an hour afterward the user can either log in again or get a refresh token. For more information about token generation, you can check here.

Define API routes

Okay now that we're done with all the heavy lifting, let's define our API endpoints(routes). We do this by navigating to the routes\api.php file in our application.
Configure the file by adding these

Route::post('register', 'AuthController@register');
Route::post('login', 'AuthController@login');
Route::get('logout', 'AuthController@logout');
Route::get('user', 'AuthController@getAuthUser');

All these routes point to the functions defined in the AuthController, we will see how they work by testing them with postman in a while.
You can verify that the routes have been registered by running php artisan route:list`
That concludes the set up of the user handling. We will now test that the API works.

Testing

For testing purposes, we will use postman to determine whether the app meets our expectations and functionality.
Before we begin testing, ensure that the local laravel server is up by running php artisan serve Turn on xampp or whichever MySQL server you are using.

note: the API requests need the header, accept:application/json

registration

registration

log in

login

failed login handling

failed login

checking the currently logged in user

Observe that you set the authorization as bearer token, copy the access token provided after logging in and paste it in the token text box
logged in user

logging out

log out

That completes everything you need to get your user registration and authentication api with laravel. Thanks for reading this post, if you have any problem with the API you can always get in touch on twitter :)

In the next part of this series, we're going to be making a CRUD API with laravel resources that enable our users to upload books and review them as well...

CRUD API with laravel and JWT (2 Part Series)

1) Handling user registration and authentication on a laravel API using jwt 2) How to create an API with laravel resources

Posted on by:

tngeene profile

Ted Ngeene

@tngeene

Backend developer working with Php(laravel), python(django) with a keen interest in PWAs. I work out and play with my dogs 🐶

Discussion

markdown guide
 

@ted I'm also on Laravel. On the topic of Auth, have you gotten Laravel Passport and Laravel Socialite working together? Would love to see an article on API-based social auth using Laravel Passport and Socialite. This is the closest thing I could find but getting it working is challenging - it's complicated. itnext.io/laravel-api-authenticati...

 

Hi.No I haven't tried it out yet, but I can check it out in a few days and give you my feedback...

 

@ted sounds great...look forward to seeing it.

 

Thanks Man It Worked Nice Love You Really ❤❤❤

 

I'm glad it worked out well. You're welcome

 

Nice job pls i need help how to set jwt expire at to be in UTC

"expires_in": "2020-06-13 12:20:00"
Instead of
expires_in": 3600

 

@ted - Please note that v1.0 isn't suitable for Production use.