Create API Rest with Laravel 7.X Passport Authentication And Implement Refresh Token (Part 1)
Tags: php, laravel, authentication, api
Published: 2020-03-13 21:21:01

you can find the newer article about this in [here](https://dev.to/azibom/how-do-you-make-laravel-7-api-authentication-with-passport-like-a-master-2p67)
## Step 1. Install Laravel
With this command we install laravel
```
laravel new website
```

## Step 2. Install Laravel Passport Package And Guzzle
Laravel Passport provides a full OAuth2 server implementation
```
composer require laravel/passport
composer require guzzlehttp/guzzle
composer require symfony/psr-http-message-bridge
```

## Step 3. Run These Commands For Fixing Storage Permission
```
sudo chown -R $USER:www-data storage
sudo chmod -R 775 storage
```

## Step 4. Run Migration
Create the tables that your application needs to store clients and access tokens
```
php artisan migrate
```

## Step 5. Generate keys
With this commend you create "personal access" and "password grant" that you need them for generating access tokens 
```
php artisan passport:install
```

## Step 6. Add Trait To User Class
There are some helper functions in this trait
```php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;class User extends Authenticatable #chenged
{
    use Notifiable, HasApiTokens; #changed
...
```

## Step 6. Call Passport Routes And Add Some Configs
call the Passport::routes method within the boot method of your AuthServiceProvider and change the token life time like this
```php
<?php

namespace App\Providers;

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

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::routes();
        Passport::tokensExpireIn(Carbon::now()->addDays(1));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(10));
    }
}

```
## Step 7. Finally You Need To Change The Api Driver
you need change api drive in config/auth.php like this
```php
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
```

Step 8. Create api route
```php
<?php

use Illuminate\Support\Facades\Route;

Route::post('login', 'UserController@login');
Route::post('register', 'UserController@register');
```

Step 9. Create controller
```
php artisan make:controller UserController
```


Step 10. Complete the controller
```php
<?php

namespace App\Http\Controllers;

use App\User; 
use Validator;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; 
use Laravel\Passport\Client as OClient; 

class UserController extends Controller
{
    public $successStatus = 200;

    public function login() { 
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) { 
            $oClient = OClient::where('password_client', 1)->first();
            return $this->getTokenAndRefreshToken($oClient, request('email'), request('password'));
        } 
        else { 
            return response()->json(['error'=>'Unauthorised'], 401); 
        } 
    }

    public function register(Request $request) { 
        $validator = Validator::make($request->all(), [ 
            'name' => 'required', 
            'email' => 'required|email|unique:users', 
            'password' => 'required', 
            'c_password' => 'required|same:password', 
        ]);

        if ($validator->fails()) { 
            return response()->json(['error'=>$validator->errors()], 401);            
        }

        $password = $request->password;
        $input = $request->all(); 
        $input['password'] = bcrypt($input['password']); 
        $user = User::create($input); 
        $oClient = OClient::where('password_client', 1)->first();
        return $this->getTokenAndRefreshToken($oClient, $user->email, $password);
    }

    public function getTokenAndRefreshToken(OClient $oClient, $email, $password) { 
        $oClient = OClient::where('password_client', 1)->first();
        $http = new Client;
        $response = $http->request('POST', 'http://mylemp-nginx/oauth/token', [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => $oClient->id,
                'client_secret' => $oClient->secret,
                'username' => $email,
                'password' => $password,
                'scope' => '*',
            ],
        ]);

        $result = json_decode((string) $response->getBody(), true);
        return response()->json($result, $this->successStatus);
    }
}

```


Step 11. Now lets test it
```
php artisan serve
```

## Step 12. It works like a charm
#### You first need to register like this
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aypwempfr4yt7sfyywov.png)
#### And then you can register and give your tokens again
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wushy2e658l2tlt1cbhc.png)

In the next parts we will make some private routes that need token, handle the exceptions and implement refresh token scenario

[Create API Rest with Laravel 7.X Passport Authentication And Implement Refresh Token (Part 2)](https://dev.to/azibom/create-api-rest-with-laravel-7-x-passport-authentication-and-implement-refresh-token-part-2-d91)