In this article, we will discuss how to create Laravel 5.6 Custom Token Base API Authentication. As we discuss the JWT Auth in our previous article. But Laravel is open to creating a custom authentication for our API’s. I’m assuming you are familiar with the Laravel framework if not then you can start with given tutorials.
- Laravel Setup
- Laravel Default Authentication Setup
- Custom User Email Verification / Activation
- Understanding Laravel Middleware
- All You Need to Know Laravel Routing
- Setup Virtual Host with Xampp Server
Table of Contents
Setup Laravel 5.6 Custom Token Base API Authentication
Create APIToken Middleware
Let’s create a middleware name APIToken. Basically, its used to protect our API where we need the user to login. You can get more details on middleware here.
Use the given command to create middleware.
php artisan make:middleware APIToken
Newly created APIToken.php middleware located at app/Http/Middleware. Just open the middleware and update the handle function as per given code.
public function handle($request, Closure $next) { if($request->header('Authorization')){ return $next($request); } return response()->json([ 'message' => 'Not a valid API request.', ]); }
In the above code snippet, we are checking the request header. Is header contains the Authorization Token? If the token is available then request is processed to next request otherwise an error message thrown.
Now time to update the newly create middleware in Kernel.php.
protected $routeMiddleware = [ ... 'APIToken' => \App\Http\Middleware\APIToken::class, ... ];
Setup Migration for API Token
Use the given command to create a migration.
php artisan make:migration add_api_token_user_table --table=users
After command execution, migration file is located at database/migrations.
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddApiTokenInUsers extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('api_token',100)->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->string('api_token',100)->nullable(); }); } }
Setup AuthController
Use the given command to create the AuthController.
php artisan make:controller API/AuthController
After, execution of above command. The controller is located at app/Http/Controller/API directory. We will add our logic for Login, Register, and Logout functionality.
<?php namespace App\Http\Controllers\API; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use DB; use App\User; use Validator; class AuthController extends Controller { private $apiToken; public function __construct() { // Unique Token $this->apiToken = uniqid(base64_encode(str_random(60))); } /** * Client Login */ public function postLogin(Request $request) { // Validations $rules = [ 'email'=>'required|email', 'password'=>'required|min:8' ]; $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { // Validation failed return response()->json([ 'message' => $validator->messages(), ]); } else { // Fetch User $user = User::where('email',$request->email)->first(); if($user) { // Verify the password if( password_verify($request->password, $user->password) ) { // Update Token $postArray = ['api_token' => $this->apiToken]; $login = User::where('email',$request->email)->update($postArray); if($login) { return response()->json([ 'name' => $user->name, 'email' => $user->email, 'access_token' => $this->apiToken, ]); } } else { return response()->json([ 'message' => 'Invalid Password', ]); } } else { return response()->json([ 'message' => 'User not found', ]); } } } /** * Register */ public function postRegister(Request $request) { // Validations $rules = [ 'name' => 'required|min:3', 'email' => 'required|unique:users,email', 'password' => 'required|min:8' ]; $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { // Validation failed return response()->json([ 'message' => $validator->messages(), ]); } else { $postArray = [ 'name' => $request->name, 'email' => $request->email, 'password' => bcrypt($request->password), 'api_token' => $this->apiToken ]; // $user = User::GetInsertId($postArray); $user = User::insert($postArray); if($user) { return response()->json([ 'name' => $request->name, 'email' => $request->email, 'access_token' => $this->apiToken, ]); } else { return response()->json([ 'message' => 'Registration failed, please try again.', ]); } } } /** * Logout */ public function postLogout(Request $request) { $token = $request->header('Authorization'); $user = User::where('api_token',$token)->first(); if($user) { $postArray = ['api_token' => null]; $logout = User::where('id',$user->id)->update($postArray); if($logout) { return response()->json([ 'message' => 'User Logged Out', ]); } } else { return response()->json([ 'message' => 'User not found', ]); } } }
In the above code snippet, AuthController.php contains three function Login, Register, and Logout. Also, class constructor contains a unique token. Let’s discuss those functions in detail:
Login Function, require email id and password. And return unique access token. Which is used in further API calls where user authentication is required.
Register Function, require name, email, and password. And return the user details with an access token. Also, you can check this. I’m using Laravel default validator for the validations. The Validator check for required fields, minimum character length and most important check for unique email and password. If an email and phone no already registered then validator thrown an error.
Both functions Login and Register store the unique api_token in the database. When Login API called then the new api_token will be generated and stored in the database.
Logout Function, require only access token in the form of the request header. In our example, we are using a Bearer Token that means Bearer keyword is added to the token. We will split this keyword at the time of the query for the user check. Then simply forget this token, so that token is not valid for the further API calls.
Setup API Route
Laravel provides an option to make separate all the API routes from the web-routes. All the API routes added in the api.php located at routes directory.
Route::prefix('v1')->namespace('API')->group(function () { // Login Route::post('/login','AuthController@postLogin'); // Register Route::post('/register','AuthController@postRegister'); // Protected with APIToken Middleware Route::middleware('APIToken')->group(function () { // Logout Route::post('/logout','AuthController@postLogout'); }); });
We are using a prefix to add additional value to the API URL.
After setup the route, time to test our API’s.
Register a new user using API.
Register API returns name, email, and access_token. An access token is used in further API call. The app developer can use this token to authenticate the users.
Login a registered user.
Login API returns same as like register API.
Logout API
Logout API receive request header with key Authorization. And return message after success. If a token is not found in the database then an error is thrown.
Conclusion
In this article, we will discuss the Laravel 5.6 Custom Token Base API Authentication. I know lots of packages available to achieve this kind of functionality such as JWT Authentication, Laravel Passport and many more. We will discuss those in future. Hope the basic idea behind the token base API is clear to you. Please feel free to add the comment if any query.
If you like our content, please consider buying us a coffee.
Thank you for your support!
Buy Me a Coffee
How to add filters like sortBy, search, perPage etc etc??
Hi Orihime,
Please update your question, where you want to apply those filters?
Hi,
Nice tutorial. But do you think the middleware is correct? Your middleware checks if the token exists only. But it should also check where the token resembles with the access_token stored in database during login.
Thank you.
Hi Md Nazim M. Khan,
Yes, In this example middleware just check token is available in the request or not. You can extend this middleware per your requirement.
thanks.
thanks a lot, this works perfectly.
I FOLLOW YOUR CODE STEP BY STEP BUT STILL MY LOGOUT FUNCTIONALITY IS NOT WORKING IT THROWS MESSAGE Not a valid API request.
Hi Aayushi, Please explain your issue more 🙂
Hello, I am facing same issue like aayushi faced. when i check in middlware $request is not able to catch the token. so it will execute next statement.
Can I use this process in my API request,is this secure or should I go for Passport or Laravel
Laravel #Jwt
Hi Rahul,
It depends on you, which is useful for your application. It maybe Custom token Auth, Laravel JWT / Laravel JWT or Laravel Passport.
It is very use full and simple method
Thanks
Genial. Me ayudo mucho. Ni en la documentación oficial de Laravel explican bien.
this error coming all the time:
ReflectionException:
Class App\Http\Controllers\API\Request does not exist
I was have problem with JWT authentication, but , I found your tutorial that save my life, thanks
Hi,
All the things work correctly. Need help, after login when i check Auth::user(), it does not return anything. can you help me how can i get logged in user data after using postLogin api.
Thanks in advaced.
Hi beena,
Please recheck once, and send more details. As per the example in the article, this is tested and working fine.
But, has not been tested with the latest version.
Hi,
As in the postLogin function, we only check the if users exist and password is matched. We are not logging in User. So when i check Auth::user(), it returns empty.
Thanks
In postLogin, you receive the user data in JSON. You need send the access_token with each API call.
Hi,
I followed your tutorial and got following error.
Not a valid API request.
I’m using Laravel 6. Can you post your APIToken Middleware full code