Today most of the applications are using laravel rest api otp login and registration without password for ease of login and registration and also provides easy to login without remembering the password each time while login or register. In Laravel there is multiple ways to implement the login and registration like Laravel provides its own auth with packages Jetstream, passport,sanctum, breeze and fortify.
These all packages are easy to install and configure but sometimes our application requirement and design patterns are different or we can say we want fully customized solution. Therefore we have already covered simple login and registration in out last article and today i am going to share rest api OTP Login and Registration Without Password using Ajax.
This example will work in all version of laravel including laravel 5, laravel 6, laravel 7, laravel 8 and laravel 9. In example we will use session to store the otp token and mail services to send the otp you can also use phone number and sms services to send the otp to mobile as well.
For this tutorial we will use jQuery for Ajax request and form validation. Bootstrap for better ui experience.
Let’s begin the tutorial of Laravel rest api OTP Login and Registration Without Password step by step
Step 1: Create a laravel project
First step is to create the Laravel project using composer command or you can also read the How to install laravel 8 ? and Laravel artisan command to generate controllers, Model, Components and Migrations
composer create-project laravel/laravel example-app
Step 2: Configure database and table
Next step is to configure the database for our project, table and data. I assuming you have created the database using MySQL command line or phpMyAdmin then open .env or if file not exist then rename .env.example file to .env
file in root folder and change database details accordingly.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=password
Next, Laravel comes with default users, reset password etc migration and user model. Thus run the artisan command to create the user table in database using below command in command line(root directory of project)
php artisan migrate
Step 3: Create a Controller
Now, Create a controller manually in app\Http\Controllers
or create using artisan command
php artisan make:controller AuthController
Above command will create a controller in app\Http\Controllers\AuthController.php
and now open the controller and replace code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
use Illuminate\Support\Facades\Crypt;
class AuthController extends Controller
{
function registerLoginView()
{
return view("login");
}
function sendOtp(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email', // required and email format validation
]); // create the validations
if ($validator->fails()) //check all validations are fine, if not then redirect and show error messages
{
return response()->json($validator->errors(), 422);
// validation failed return with 422 status
} else {
//validations are passed try login using laravel auth attemp
$otp = rand(1000, 9999);
$time = time();
$email = $request->email;
// Or you can stroe it in table
$encryptedOtpTokenStr = json_encode(["o" => $otp, "t" => $time, "e" => $email]);
$secret = Crypt::encryptString($encryptedOtpTokenStr);
//you can send sms here as well if its a phone number
// \Mail::to($email)->send(new \App\Mail\OtpMail($otp));
$response = ['status' => true, "message" => "Otp sent to your email address","secret"=>$secret];
return response()->json($response);
}
}
function verifyOtpAndLogin(Request $request)
{
$validator = Validator::make($request->all(), [
// required and email format validation
'otp' => 'required',
'secret'=>'required'
]); // create the validations
if ($validator->fails()) //check all validations are fine, if not then redirect and show error messages
{
return response()->json($validator->errors(), 422);
// validation failed return with 422 status
} else {
try {
$decryptedString = Crypt::decryptString($request->secret);
$json = json_decode($decryptedString);
$time = time();
if (($time - $json->t) <= 120) { // check otp is not expired (Expiration time 120 seconds which 2 min you can increase)
if ($json->o == $request->otp) {
if (User::whereEmail($json->e)->count() <= 0) {
$user = new User;
$user->email = $json->e;
$user->username = '';
$user->phone_number = "";
$user->save();
} else {
$user = User::whereEmail($json->e)->first();
}
\Auth::guard()->login($user);
return response()->json(["status" => true, "msg" => "login successful", "redirect_location" => url("dashboard")]);
}
}
return response()->json([["Invalid OTP or Request2"]], 422);
} catch (\Exception $e) {
return response()->json([["Invalid OTP or Request1", $e->getMessage()]], 422);
}
}
}
// logout method to clear the sesson of logged in user
function logout()
{
\Auth::logout();
return redirect("login")->with('success', 'Logout successfully');;
}
}
Here we have used Illuminate\Support\Facades\Validator
to validate the input fields, Auth
class to authenticate user in Laravel.
sendOtp
to send the otp to user email or phone number , here this method we used Crypt
library to encrypt the random otp, email and time. Time is used to allow users to use otp for specific time then we sent the token into response.
verifyOtpAndLogin
method use for verifying the otp so we will match the input otp by user and session otp with given time and create the session of user using Auth::login()
and here the which is noticeable is we have change the response()->json()
, dashboard
to show dashboard page after login and logout
to destroy the session.
There is no need to set session manually in Laravel, Laravel creates own session using Auth::login()
method and we can get current logged in user using \Auth::user()
.
Step 4 : Generate Mailable Class
This is optional step if you are using sms service for otp, In laravel 8 or 9 every mail is implements mailable class thus first we need to create a mail class as follow or read How to Send Mail in Laravel Through Gmail SMTP ?
php artisan make:mail OtpMail
This will create a class in following location App\Mail\OtpMail.php
Update the code as below
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class OtpMail extends Mailable
{
use Queueable, SerializesModels;
private $otp;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($otp)
{
$this->otp=$otp;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->from('info@readerstacks.com')
->subject('OTP for login from readerstacks.com')
->view('email-otp',["otp"=>$this->otp,"title"=>"OTP"]);
}
}
Step 5: Create Email views
We have created logic for login and register, now its time to create our email view
<!DOCTYPE html>
<html>
<head>
<title>Readerstacks.com</title>
</head>
<body>
<h1>Hello </h1>
<p>Your OTP for login is {{$otp}}</p>
<p>Thanks to visit us.</p>
</body>
</html>
Step 5: Create routes
Now, create the routes for all pages and method in routes\api.php
<?php
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
Route::post('/send-otp', [AuthController::class,"sendOtp"]);
Route::post('/verify-otp-login', [AuthController::class,"verifyOtpAndLogin"]);
Route::get('/logout', [AuthController::class,"logout"]);
Now start the application using php artisan serve
then you can access the URLs.
Also Read : Laravel OTP Login and Registration Without Password