Skip to content

Instantly share code, notes, and snippets.

@yaza-putu
Last active August 17, 2020 04:52
Show Gist options
  • Save yaza-putu/b1892eb8373a13d6ae1e1e016907ef0e to your computer and use it in GitHub Desktop.
Save yaza-putu/b1892eb8373a13d6ae1e1e016907ef0e to your computer and use it in GitHub Desktop.
Install and config JWT Auth Laravel

Install & Auth With JWT In Laravel

Install JWT

documentations https://jwt-auth.readthedocs.io/en/develop/laravel-installation/

  composer require tymon/jwt-auth

Add the service provider to the providers array in the config/app.php config file as follows:

'providers' => [

    ...

    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]

Create Alias

'aliases' => [
...
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
]

Publish the config Run the following command to publish the package config file:

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

Generate secret key

php artisan jwt:secret

make database

php artisan make:migration CreateAdmins

config

  public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('username')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

Create Model

make model

php artisan make:model Models/Admin

Config

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
//jwt
use Tymon\JWTAuth\Contracts\JWTSubject;
class Admin extends Authenticatable implements JWTSubject
{
    use Notifiable;

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

    /**
     * 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',
    ];
    
    // JWT function

    /**
     * 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 [];
    }
}

Add Guard

Add guard on config/auth.php

// set driver as 'jwt'
'guards' => [
...
 'admin_api' => [
      'driver' => 'jwt',
      'provider' => 'admin_api',
      'hash' => false,
  ],
]
...
'providers' => [
...
  'admin_api' => [
      'driver' => 'eloquent',
      'model' => App\Models\Admin::class,
  ],
]
...
// for reset password
'passwords' => [
...
  'admin_api' => [
      'provider' => 'admin_api',
      'table' => 'password_resets',
      'expire' => 60,
      'throttle' => 60,
  ],
]

Create middleware

Make middleware

php artisan make:middleware Jwt

config

<?php

namespace App\Http\Middleware;

use Closure;
use Exception;
//jwt
use JWTAuth;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class Jwt extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        try {
            $user = JWTAuth::parseToken()->authenticate();
        } catch (Exception $e) {
            if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
                return response()->json(['status' => 'Token is Invalid']);
            }else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
                return response()->json(['status' => 'Token is Expired']);
            }else{
                return response()->json(['status' => 'Authorization Token not found']);
            }
        }
        return $next($request);
    }
}

Register Middleware in kernel

protected $routeMiddleware = [
...
'jwt'       => \App\Http\Middleware\Jwt::class,
]

Config Route API

Route::namespace('Api')->group(function(){
    // Admin
    Route::name('Admin.')->prefix('admin')->namespace('Admin')->group(function(){
        Route::post('login', 'LoginController@login')->name('Login');
        // need token
        Route::middleware('jwt')->group(function(){
            Route::post('logout', 'LoginController@logout')->name('Logout');
            Route::post('refresh', 'LoginController@refresh')->name('Refresh');
        });
    });

});

Create Controller

php artisan make:controller Api\Admin\LoginController

Config on LoginController on login you can input username or email,set name input as name="username" server will cek your input value username or email

<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
//jwt
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class LoginController extends Controller
{
    protected $username = 'username';

    public function __construct()
    {
        $this->username = $this->findUsername();
    }

    public function findUsername()
    {
        $login = request()->input('username');
 
        $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
 
        request()->merge([$fieldType => $login]);
 
        return $fieldType;
    }

    public function username()
    {
        return $this->username;
    }

    public function login(Request $request)
    {
        $credentials = $request->only('username', 'password');            
        if(! $token = Auth::guard('admin_api')->attempt([$this->username() => $credentials['username'], 'password' => $credentials['password']])){
            return response()->json(['error' => 'Unauthorized'], 401);
        }else{           
            return $this->respondWithToken($token);
        }
    }

    public function logout(Request $request)
    {
        auth('admin_api')->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh(Request $request)
    {
        return $this->respondWithToken(auth('admin_api')->refresh());
    }
    //jwt create token
    protected function respondWithToken($token)
    {
        return response()->json([
            'token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('admin_api')->factory()->getTTL() * 60,
       ]);
    }
}

How to Use JWT

Test API with postman or whatever

Login

if you succes login you can get a token from server example response

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MlwvYXBpXC9hZG1pblwvbG9naW4iLCJpYXQiOjE1OTc1ODYzOTYsImV4cCI6MTU5NzU4OTk5NiwibmJmIjoxNTk3NTg2Mzk2LCJqdGkiOiJPWlo3RW9NM0RlY2JCYjZtIiwic3ViIjoxLCJwcnYiOiJkZjg4M2RiOTdiZDA1ZWY4ZmY4NTA4MmQ2ODZjNDVlODMyZTU5M2E5In0.1EnIf3BBH053F6HyB7JoPcT_HpEEhqNAwPCO-s8Kodg","token_type":"bearer","expires_in":3600,"data":{"id":1,"name":"Admin","email":"admin@gmail.com","username":"admin","email_verified_at":null,"created_at":"2020-08-16T11:40:27.000000Z","updated_at":"2020-08-16T11:40:27.000000Z"}}

Authenticated requests

There are a number of ways to send the token via http:

Authorization header set header

Authorization: Bearer eyJhbGciOiJIUzI1NiI...

or method post with Query string parameter

http://example.dev/me?token=eyJhbGciOiJIUzI1NiI...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment