JWT Authentication (Laravel Part )
Start coding with me to complete JWT authentication and send API from the laravel side(Back End)
Notes:
1- We suppose that you have already fixed your env file and connected it to your database.
2- This article is an application of another article but here we just apply the part of authentication in a short and understandable way with small differences and without adding other stuff.
3- The original article :
https://www.avyatech.com/rest-api-with-laravel-8-using-jwt-token/
Steps:
1- Install JWT Package.
2- Edit app.php inside the config folder.
3- Publish JWT configuration.
4- Generate JWT Key.
5- Create JWT middleware.
6- Create API routes.
7- Create AuthController.
8- Edit the User model.
9- Migrate your database.
1- To install the JWT package:
composer require tymon/jwt-auth
2- Add the following to app.php inside config:
//inside providers'providers' => [
….
'Tymon\JWTAuth\Providers\LaravelServiceProvider',
],//inside aliases'aliases' => [
….
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
3- To publish JWT configuration:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
4- To generate JWT key:
php artisan jwt:secret //this will create JWT key inside env file
5- To create JWT middleware:
php artisan make:middleware JwtMiddleware
Next copy the following and past it inside the new middleware file:
<?phpnamespace App\Http\Middleware;use Closure;use Exception;use JWTAuth;use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;class JwtMiddleware 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);}}
Now in the kernel.php(inside Http folder) add the following to the routeMiddleware array:
...
protected $routeMiddleware = [ ...
'jwt.verify' => \App\Http\Middleware\JwtMiddleware::class,
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
]; ...
6- To create API routes:
Route::post('login', [AuthController::class, 'authenticate']);Route::post('register', [AuthController::class, 'register']);Route::group(['middleware' => ['jwt.verify']], function () {Route::get('logout', [AuthController::class, 'logout']);Route::get('get_user', [AuthController::class, 'get_user']);});
7- To create AuthController:
php artisan make:controller AuthController
Now inside the controller put the following:
<?phpnamespace App\Http\Controllers;use JWTAuth;use App\Models\User;use Illuminate\Http\Request;use Tymon\JWTAuth\Exceptions\JWTException;use Symfony\Component\HttpFoundation\Response;use Illuminate\Support\Facades\Validator;class AuthController extends Controller{public function register(Request $request){//Validate data$data = $request->only('name', 'email', 'password');$validator = Validator::make($data, ['name' => 'required|string','email' => 'required|email|unique:users','password' => 'required|string|min:6|max:50']);//Send failed response if request is not validif ($validator->fails()) {return response()->json(['error' => $validator->messages()], 400);}//Request is valid, create new user$user = User::create(['name' => $request->name,'email' => $request->email,'password' => bcrypt($request->password)]);//User created, return success responsereturn response()->json(['success' => true,'message' => 'User created successfully','data' => $user], Response::HTTP_OK);}public function authenticate(Request $request){$credentials = $request->only('email', 'password');//valid credential$validator = Validator::make($credentials, ['email' => 'required|email','password' => 'required|string|min:6|max:50']);//Send failed response if request is not validif ($validator->fails()) {return response()->json(['error' => $validator->messages()], 400);}//Request is validated//Crean tokentry {if (! $token = JWTAuth::attempt($credentials)) {return response()->json(['success' => false,'message' => 'Login credentials are invalid.',], 400);}} catch (JWTException $e) {return $credentials;return response()->json(['success' => false,'message' => 'Could not create token.',], 500);}//Token created, return with success response and jwt tokenreturn response()->json(['success' => true,'token' => $token,]);}public function logout(Request $request){//valid credential$validator = Validator::make($request->only('token'), ['token' => 'required']);//Send failed response if request is not validif ($validator->fails()) {return response()->json(['error' => $validator->messages()], 400);}//Request is validated, do logouttry {JWTAuth::invalidate($request->token);return response()->json(['success' => true,'message' => 'User has been logged out']);} catch (JWTException $exception) {return response()->json(['success' => false,'message' => 'Sorry, user cannot be logged out'], Response::HTTP_INTERNAL_SERVER_ERROR);}}public function get_user(Request $request){$this->validate($request, ['token' => 'required']);$user = JWTAuth::authenticate($request->token);return response()->json(['user' => $user]);}}
8- Edit the user model:
Your User model should be like this :
<?phpnamespace 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 Tymon\JWTAuth\Contracts\JWTSubject;class User extends Authenticatable implements JWTSubject{use HasFactory, Notifiable;/*** The attributes that are mass assignable.** @var array*/protected $fillable = ['name', 'email', 'password',];/*** 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',];public function getJWTIdentifier(){return $this->getKey();}public function getJWTCustomClaims(){return [];}}
9- To Migrate your database:
php artisan migrate
Now your Authentication should work normally when you test it in postman:
-Register API:
-Login API:
-Logout API: