PHP LogoLaravel Passport

Laravel Passport is a full OAuth2 server implementation for Laravel applications, making API authentication a breeze. It provides a robust, easy-to-use solution for authenticating API requests using various OAuth2 grant types.

What is OAuth2?
OAuth2 (Open Authorization 2.0) is an industry-standard protocol for authorization. It allows a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. In simpler terms, it enables secure delegated access to protected resources.

Why Use Laravel Passport?

1. Full OAuth2 Server: Implements the entire OAuth2 specification, including various grant types.
2. Easy Setup: Integrates seamlessly with existing Laravel projects with simple Artisan commands.
3. API Authentication: Provides a standardized and secure way to authenticate requests to your API.
4. First-Party & Third-Party Clients: Supports both your own applications (e.g., mobile apps, SPAs) and external third-party applications.
5. Token Management: Handles token creation, revocation, and refresh tokens.

Key Features and Grant Types Supported:

* Personal Access Tokens: Ideal for users who want to access their own data via an API, perhaps through a script or command-line tool. These are long-lived tokens that bypass the full OAuth authorization flow.
* Password Grant: Suitable for first-party clients (e.g., your own mobile app) where the user trusts your application with their username and password. The client exchanges these credentials for an access token.
* Client Credentials Grant: Used for machine-to-machine authentication where a client needs to access resources not on behalf of a user, but on its own behalf (e.g., a service communicating with another service).
* Authorization Code Grant: The most common and secure grant type for third-party applications. It involves redirecting the user to your application for authorization and then exchanging an authorization code for an access token.
* Implicit Grant: (Though deprecated in OAuth 2.1) Was typically used by client-side browser-based applications (SPAs) where the token is returned directly in the redirect URI fragment after authorization.

How Laravel Passport Works (High-Level):
1. Installation: You install Passport via Composer and run migrations to add the necessary tables for clients and tokens.
2. Configuration: Your `User` model uses the `HasApiTokens` trait, and your `AuthServiceProvider` registers Passport's routes.
3. Token Issuance: Depending on the grant type, your Laravel application issues access tokens (and sometimes refresh tokens) to clients.
4. API Access: Clients include the access token in the `Authorization: Bearer {token}` header when making requests to protected API endpoints.
5. Token Verification: Laravel's `auth:api` middleware (configured to use the Passport driver) verifies the token, authenticating the user or client making the request.

Laravel Passport significantly simplifies the complex task of building a secure and scalable API authentication system within your Laravel applications.

Example Code

```php
// 1. Installation
// Require Passport via Composer
// composer require laravel/passport

// Run database migrations to create Passport's tables
// php artisan migrate

// Install Passport to create encryption keys and a "Personal Access Client"
// php artisan passport:install

// 2. Add HasApiTokens Trait to your User Model
// app/Models/User.php
namespace 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 Laravel\Passport\HasApiTokens; // Import the HasApiTokens trait

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable; // Use the trait

    /
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

// 3. Register Passport's Routes in AuthServiceProvider
// app/Providers/AuthServiceProvider.php
namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport; // Import Passport

class AuthServiceProvider extends ServiceProvider
{
    /
     * The policy mappings for the application.
     *
     * @var array<class-string, class-string>
     */
    protected $policies = [
        // 'App\Models\Model' => 'App\Policies\ModelPolicy',
    ];

    /
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        if (! $this->app->routesAreCached()) {
            Passport::routes(); // Register Passport's authentication routes
        }

        // Optional: Define token lifetimes (example)
        // Passport::tokensExpireIn(now()->addDays(15));
        // Passport::refreshTokensExpireIn(now()->addDays(30));
        // Passport::personalAccessTokensExpireIn(now()->addMonths(6));
    }
}

// 4. Configure API Authentication Guard
// config/auth.php
// Ensure your 'api' guard uses the 'passport' driver

/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| You may define every authentication guard for your application. Of course,
| every guard configuration should have a provider to pull users from. An
| example configuration has been provided for you here.
|
*/

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport', // Change this from 'token' to 'passport'
        'provider' => 'users',
        'hash' => false,
    ],
],

// 5. Protect API Routes
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

// This route will return the authenticated user's data
Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

// This is an example of a protected resource endpoint
Route::middleware('auth:api')->get('/protected-data', function (Request $request) {
    return response()->json(['message' => 'You accessed protected data!', 'user_id' => $request->user()->id]);
});

// 6. Generating a Personal Access Token (e.g., in `php artisan tinker` or a temporary route)
// You would typically generate these for your own use or through an admin panel.

// Example in Tinkerwell or a custom command/route for an authenticated user:
// $user = App\Models\User::factory()->create(); // Create a dummy user
// $token = $user->createToken('My Personal Access Token')->accessToken;
// echo "Personal Access Token: ".$token; // This token can now be used to access API routes

// If you already have a user (e.g., user with ID 1):
// $user = App\Models\User::find(1);
// if ($user) {
//     $token = $user->createToken('My API Token')->accessToken;
//     echo "Access Token: ".$token;
// } else {
//     echo "User not found.";
// }

// 7. Making an API Request with the Token (Conceptual using cURL)
// Assuming you obtained an access token (e.g., 'YOUR_ACCESS_TOKEN_HERE')

// Request to /api/user
// curl -H "Accept: application/json" \
//      -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
//      http://your-laravel-app.test/api/user

// Expected response (if token is valid):
// {"id":1,"name":"John Doe","email":"john@example.com","email_verified_at":null,"created_at":"...","updated_at":"..."}

// Request to /api/protected-data
// curl -H "Accept: application/json" \
//      -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
//      http://your-laravel-app.test/api/protected-data

// Expected response (if token is valid):
// {"message":"You accessed protected data!","user_id":1}

// If the token is invalid or missing, you'd typically get a 401 Unauthorized response.
```