Hello Artisan
In this tutorial, I am coming with a brand new tutorial. In this tutorial, I will show you how we can login with laravel passport. Here I will create two login parts, one for the user and the other for admin. Only the admin can access all of the admin features, not the user.
In this tutorial, we are going to learn about laravel passport. In this tutorial, I will show you step by step that how to create API authentication using laravel passport. In this laravel passport tutorial, I will also show you user access control using laravel passport scope.
Scopes allow your application's users to limit the actions a third-party application can perform on their behalf. Laravel passport token scope provides you beautiful services.
Scopes allow your API clients to request a specific set of permissions when requesting authorization to access an account. For example, if you are building an e-commerce application, not all API consumers will need the ability to place orders.
Instead, you may allow the consumers to only request authorization to access order shipment statuses. In this example we will also see laravel passport roles permissions from scratch so that you can understand all of that thing clearly.
So let's start our laravel passport API tutorial.
Let's start building our Rest Api using laravel passport authentication with scopes.
Step 1: Install Laravel
I am going to explain step by step from scratch so, we need fresh Laravel 7 application using bellow command
composer create-project --prefer-dist laravel/laravel ApiAuth
Step 2: Install Passport
In this step we need to setup laravel/passpor package for passport method. so open your terminal and fire bellow command:
composer require laravel/passport
After successfully install package, open config/app.php file and add service provider.
config/app.php
'providers' => [
....
Laravel\Passport\PassportServiceProvider::class,
],
Step 3: Run Migration Command
After adding avobe service provider, we need to run migration command, after run migration command you will get several new tables in database. So, let's run bellow command:
php artisan migrate
Read also: Laravel 6 | Create API Authentication using Laravel Passport
Next, we need to install passport using command, Using passport:install command, it will create token keys for security. So let's run bellow command:
php artisan passport:install
Step 4: Passport Configuration
Now time to setup laravel passport confugartion. So let's do below things. We need HasApiTokens trait in our User model. So add it like below
app/User.php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
app/Providers/AuthServiceProvider.php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
Now configure our auth.php file. Here our default api driber is token. Just replace it with passport.
config/auth.php
return [
.....
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
.....
]
Step 5 : Setup API Route
In this step, we will create api routes. Laravel provide api.php file for write web services route. So, let's add new route on that file.
routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
//Auth routes
Route::post('login', 'API\AuthController@login');
Route::post('register', 'API\AuthController@register');
// Route for admin permissions
Route::prefix('admin')->group(function() {
Route::post('login', 'API\AuthController@adminLogin');
Route::post('register', 'API\AuthController@adminRegister');
});
Step 6 : Create & Setup Controller
In this step we need to create our AuthController. So let's create it and handle all of the methods here. Run below command to create it.
php artisan make:controller API/AuthController
After completing this step, copy the below code and paste it in your auth controller.
app/Http/Controllers/API/AuthController.php
namespace App\Http\Controllers\API;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class AuthController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], 200);
}
else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
public function register(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => \Hash::make($request->password),
]);
$success['name'] = $user->name;
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], 200);
}
public function adminLogin(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$success['token'] = $user->createToken('MyApp', ['*'])->accessToken;
return response()->json(['success' => $success], 200);
}
else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
public function adminRegister(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
$success['name'] = $user->name;
$success['token'] = $user->createToken('MyApp', ['*'])->accessToken;
return response()->json(['success' => $success], 200);
}
}
Look here carefully, if we request a token to have all the permissions I have defined, I would generate my token as like below.
$success['token'] = $user->createToken('MyApp', ['*'])->accessToken;
If we request a token for just one permission to perform a task, I would generate my tokens as like below:
For ‘update-task’ scope:
$success['token'] = $user->createToken('MyApp', ['update-task'])->accessToken;
But here we are going to use multiple scope together. That's why i am using (*) sign. Hope you will understand. You can read more about laravel passport scope using this link laravel paasport scope tutorial
Read also : Laravel 6 REST API with JWT Authentication with CRUD
Our login mechanism is completed, so we need to define our passport scope. You may define your API's scopes using the Passport::tokensCan
method in the boot
method of your AuthServiceProvider
. The tokensCan
method accepts an array of scope names and scope descriptions.
use Laravel\Passport\Passport;
Passport::tokensCan([
'place-orders' => 'Place orders',
'check-status' => 'Check order status',
]);
So open AuthServiceProvider and paste this below code like below
app/Providers/AuthServiceProvider.php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
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();
Passport::tokensCan([
'edit' => 'can edit books available',
'create' => 'can add new books',
'delete' => 'can delete books',
]);
Passport::routes();
}
}
Step 7 : Checking Scope
Now we need to add scope middleware. Passport includes two middleware that may be used to verify that an incoming request is authenticated with a token that has been granted a given scope. To get started, add the following middleware to the $routeMiddleware
property of your app/Http/Kernel.php
file:
app/Http/Kernel.php
protected $routeMiddleware = [
.
.
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
];
Now time to add this middleware in our routes. So open routes and paste this below code and update you api.php file.
routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
//Auth routes
Route::post('login', 'API/AuthController@login');
Route::post('register', 'API/AuthController@register');
// Route for admin permissions
Route::prefix('admin')->group(function() {
Route::post('login', 'API/AuthController@adminLogin');
Route::post('register', 'API/AuthController@adminRegister');
});
Route::get('products', 'ProductController@index');
Route::get('products/{products}', 'ProductController@show');
Route::post('product', 'ProductController@store')->middleware(['auth:api', 'scope:create']);
Route::put('product/{product}', 'ProductController@update')->middleware(['auth:api', 'scope:edit']);
Route::delete('product/{product}', 'ProductController@destroy')->middleware(['auth:api', 'scope:delete']);
If you are using middle like above, there is no need to declare it in constructor method like below.
app/Http/Controllers/ProductController.php
namespace App\Http\Controllers;
use App\Book;
use Validator;
use Illuminate\Http\Request;
use App\Http\Resources\BookResource;
class ProductController extends Controller
{
public function __construct()
{
$this->middleware(
[
'auth:api',
'scopes:edit,create,delete'
])->except(
[
'index', 'show'
]
);
}
public function index()
{
//return your all products
}
public function store(Request $request)
{
//who has create scope, only he can store the products
}
public function show($id)
{
//Show single product here
}
public function update(Request $request, $id)
{
//who has edit scope, only he can update the products
}
public function destroy($id)
{
//who has delete scope, only he can delete the products
}
}
But here in controller we are using middleware scope in constructor method. So we can use our route like below.
// Route for api endpoints
Route::apiResource('products', 'ProductController');
Hope you have understand all the process. Well we are done everything.
Once an access token authenticated request has entered your application, you may still check if the token has a given scope using the tokenCan
method on the authenticated User
instance.
Route::get('/products', function (Request $request) {
if ($request->user()->tokenCan('place-orders')) {
//user has authorised to perform this operation
}
});
Check git repository : Laravel Passport Scope
Thanks you guys for reading this article from my site, hope you have learned something new from this laravel passport scope tutorial.
#laravel #passport #api #auth #acl #permissions #roles #passport-scope #rest-api #laravel-passport #laravel-6 #laravel-7 #packages