How to create Laravel authenticate an API without using Laravel Passport
In this tutorial, we will learn How to create Laravel authenticate an API without using Laravel Passport. We learn without using Laravel Passport. So thing is that in some cases you don’t need the complexity of Laravel Passport needs. Since Laravel 5.3, Laravel Passport provides to authenticate an API consumer with an access token.
Here, for example, we build a website that provides to users a few API routes and that the user can call to update his data. Not need a full OAuth system and do not need multiple database tables to store tokens that could expire.
Simply, I just give you a unique token to users register or log in, and they use it in their API calls in authenticated.
- Add token field in users table
- Generate Token
- Use Token
- Check config file
- Check Middleware
- Authenticate the user with the token
Add token field in users table
First, add to the user’s table in api_token
the field. please follow the below command:
php artisan make:migration add_api_token_field_to_users_table
<?php #database/migrations/2021_07_14_072531_add_api_token_field_to_users_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddApiTokenFieldToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('api_token')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('api_token'); }); } }
Now run the below command to add a field in the user’s table:
php artisan migrate
Generate Token
We create the function in the model file, I have a very short and simple method to display:
<?php #app/Models/User.php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Str; #added class User extends Authenticatable { ... public function createApiToken() { $token = Str::random(64); $this->api_token = $token; $this->save(); return $token; } }
Use Token
php artisan make:controller Api\HomeController
<?php #app\Http\Controllers\Api\HomeController.php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\User; use Auth; use Validator; class HomeController extends Controller { public function login(Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required', 'password' => 'required', ]); if ($validator->fails()) { return response()->json(['error'=>$validator->errors()], 401); } if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){ $token = auth()->user()->createApiToken(); #Generate token return response()->json(['status' => 'Authorised', 'token' => $token ], 200); } else { return response()->json(['status'=>'Unauthorised'], 401); } } public function index() { $users = User::latest()->paginate(10); if($users->count()) { return response()->json(['status' => 'true' ,'data' => $users], 200); } else{ return response()->json(['status' => 'false'], 401); } } }
Check config file
Laravel by default the auth.php
the configuration file is already correctly configured. but we need to change anything, in this case just to make sure it’s ok:
#config/auth.php 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', //only check 'provider' => 'users', ], ],
Check Middleware
Laravel all API routes need to be located in the routes/api.php
. For the specific routes that need authentication middleware, only you should use the auth:api
middleware:
#routes/api.php Route::post('login', 'App\Http\Controllers\Api\HomeController@login'); Route::get('users', 'App\Http\Controllers\Api\HomeController@index')->middleware('auth:api');
Authenticate the user with the token
Just need to register for the right class at the right place.
<?php #app/Providers/AuthServiceProvider.php namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Gate; use Illuminate\Auth\TokenGuard; #added use Illuminate\Support\Facades\Auth; #added 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(); #added Auth::extend('token', function ($app, $name, array $config) { return new TokenGuard(Auth::createUserProvider($config['provider']), $app->request); }); } }