create an Auth module with laravel using nwidart/laravel-modules package
ashrakt
Posted on February 29, 2024
nwidart/laravel-modules is a Laravel package which was created to manage your large Laravel app using modules.
A module is like a Laravel package, it has some views, controllers or models.
1) create project and install nwidart/laravel-modules package
create Laravel project
composer create-project laravel/laravel module
install nwidart through Composer, by run the following command:
composer require nwidart/laravel-modules
The package will automatically register a service provider and alias.
Optionally, publish the package's configuration file by running:
php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"
2) Autoloading
- By default the module classes are not loaded automatically. You can autoload your modules using psr-4. For example :
{
"autoload": {
"psr-4": {
"App\\": "app/",
"Modules\\": "Modules/"
}
}
}
- run
composer dump-autoload
3) Generate a new module using the Nwidart package
php artisan module:make <module-name>
php artisan module:make Auth
app/
bootstrap/
vendor/
Modules/
├── Auth/
├── Assets/
├── Config/
├── Console/
├── Database/
├── Migrations/
├── Seeders/
├── Entities/
├── Http/
├── Controllers/
├── Middleware/
├── Requests/
├── routes.php
├── Providers/
├── BlogServiceProvider.php
├── Resources/
├── lang/
├── views/
├── Repositories/
├── Tests/
├── composer.json
├── module.json
├── start.php
4) install sanctun
composer require laravel/sanctum
5) Publish the Laravel Sanctum configuration file.
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
6) Create the authentication controllers within the Auth module.
php artisan module:controller LogoutController Auth
php artisan module:controller RegisterControl Auth
php artisan module:controller LoginController Auth
php artisan module:controller ForgotPasswordController Auth
php artisan module:controller ResetPasswordController Auth
7) Define the routes for authentication within the Auth module.
Create a file named routes/api.php within the Modules/Auth directory and add the following code:
Route::prefix('user')->group(function () {
Route::post('register', [RegisterController::class,'register']);
Route::post('login', [LoginController::class,'login']);
Route::post('password/forgot ', [ForgotPasswordController::class, 'sendForgotLinkEmail']);
Route::post('password/forgot/submit', [ForgotPasswordController::class, 'submitForgotPassword']);
Route::post('password/reset', [ResetPasswordController::class, 'resetPassword'])->middleware(['auth:sanctum']);
Route::post('logout', [LogoutController::class, 'logout'])->middleware(['auth:sanctum']);
});
8) add auth table in Migrations folder module
9)
- php artisan migrate
- php artisan key:generate
10) Move the User model to the Auth module's model directory
mv app/Models/User.php Modules/Auth/Models/User.php
11)Update the namespace of the User model. Open Modules/Auth/Models/User.php and modify the namespace to:
12) Update the config/auth.php file to use the Auth module's User model. In the config/auth.php file, locate the 'providers' configuration and modify it as follows:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => Modules\Auth\Models\User::class,
],
13) Open the RegisterController and add the code below in it to create the method to register a user:
use Illuminate\Support\Facades\Hash;
class RegisterController extends Controller
{
public function register(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8',
]);
$user = User::create([
'name' => $validatedData['name'],
'email' => $validatedData['email'],
'password' => Hash::make($validatedData['password']),
]);
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
}
First, we validate the incoming request to make sure all required variables are present. Once a user has been created, we create a new personal access token using the createToken() method and give the token a name of auth_token, we call the plainTextToken on the instance to access the plain-text value of the token. Finally, we return a JSON response containing the generated token as well as the type of the token.
14) Then add the login() method inside of the LoginController:
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function login(Request $request)
{
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json([
'message' => 'Invalid login details'
], 401);
}
$user = User::where('email', $request['email'])->firstOrFail();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'user' => $user,
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
}
15) forgot password
- make mail
php artisan module:make-mail ResetPassword Auth
<?php
namespace Modules\Auth\App\Emails;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class ResetPassword extends Mailable
{
use Queueable, SerializesModels;
public $data;
public function __construct($data)
{
$this->data = $data;
}
public function build()
{
return $this->subject('Mail from ashrakt')->view("auth::mails.resetPassword");
}
}
- make view
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Authentication</title>
</head>
<body>
<h3>code : {{ $data }}</h3>
</body>
</html>
- Forgot Password Controller
<?php
namespace Modules\Auth\App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Modules\Auth\Models\User;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Modules\Auth\App\Emails\ResetPassword;
class ForgotPasswordController extends Controller
{
public function sendResetLinkEmail(Request $request)
{
$request->validate([
'email' => 'required|email|exists:users',
]);
$token = Str::random(64);
DB::table('password_reset_tokens')->insert([
'email' => $request->email,
'token' => $token,
'created_at' => Carbon::now()
]);
Mail::to($request->email)->send(new ResetPassword($token));
return response()->json(['message' => 'We have e-mailed your password reset link!']);
}
public function submitResetPasswordForm(Request $request)
{
$request->validate([
'email' => 'required|email|exists:users',
'token' => 'required',
'password' => 'required|string|min:6|confirmed',
'password_confirmation' => 'required'
]);
$updatePassword = DB::table('password_reset_tokens')
->where([
'email' => $request->email,
'token' => $request->token
])->first();
if (!$updatePassword) {
return response()->json(['message' => 'Invalid token!']);
}
User::where('email', $request->email)
->update(['password' => Hash::make($request->password)]);
DB::table('password_reset_tokens')->where(['email' => $request->email])->delete();
return response()->json(['message' => 'Your password has been changed!']);
}
}
- env file
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_USERNAME=####
MAIL_PASSWORD=####
MAIL_ENCRYPTION=tls
MAIL_MAILER=smtp
MAIL_FROM_ADDRESS=####
MAIL_FROM_NAME="${APP_NAME}"
16) Reset password
<?php
namespace Modules\Auth\App\Http\Controllers;
use Illuminate\Http\Request;
use Modules\Auth\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
class ResetPasswordController extends Controller
{
public function resetPassword(Request $request)
{
$request->validate([
'email' => 'required|email|exists:users',
'password' => 'required|string|min:6|confirmed',
'password_confirmation' => 'required'
]);
User::where('email', $request->email)
->update(['password' => Hash::make($request->password)]);
return response()->json(['message' => 'Your password has been changed!']);
}
}
17) logout
<?php
namespace Modules\Auth\App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Laravel\Sanctum\PersonalAccessToken;
class LogoutController extends Controller
{
public function logout(Request $request)
{
$logout = PersonalAccessToken::findToken($request->bearerToken())->delete();
if ($logout) {
return response()->json([
'message' => 'Successfully logged out.',
]);
} else {
return response()->json([
'message' => 'Error occurred while logging out.',
]);
}
}
}
Posted on February 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024