Laravel 6.0 API認証(Passportパッケージ）を使う方法 

こんにちはプログラマーの田中です。

今回は、Laravel6.0でPassportパッケージによるAPI認証のやり方を解説します。
この記事を書いた動機は、私の方でLaravel6.0でPassportパッケージによるAPI認証のやり方を調べたのですが、複数のソースで、現在ではエラーになってしまいます。
そのため、2020年12月28日現在実行できる解説が必要でした。
私が必要だったら他の人も必要なのではないかと思い記事にしました。

### 今回の記事のゴール
Lavavel6.0にて、Passportパッケージにより認証を開発します。
具体的なAPIの機能は、下記の通りです。

- ユーザを登録できる
- ログインしたらユーザ詳細を表示できる
- ログインできる

### 前提条件

- Laravel6.0のプロジェクトを作成している
- http://localhost:8080/にて、Laravelのプロジェクトにアクセスが可能

私の場合は、下記の記事を参考にしてdockerにてLaravel６.0のプロジェクトを作成しました。
https://qiita.com/lucaspoppy/items/9c31e03dae9a1995814c

### データベースの設定

laravel6/src/.envファイルにて、データベースの情報を書き込みます。
※データベースは事前に作っておきます

```
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root
```

### ユーザテーブルの作成

データベースの設定が終わったら、ユーザテーブルを作成します。
laravel6では、ベースラインでユーザテーブルの設定があるので下記のコマンドを実行するだけです。

```
php artisan migrate
```

### Passportパッケージ

Passportパッケージをインストールする。

```
composer require laravel/passport:9.4.0
```

### データベースの更新

Passportパッケージのデータベース変更を取り込みます。 
再度migrateを実施します。

```
php artisan migrate
```

### 設定ファイルの更新

src\config\app.phpの１７７行目あたりに１行追加します。

```
    'providers' => [
    
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        Laravel\Passport\PassportServiceProvider::class, →　追加
　]
```

### Passportのインストール

下記のコマンドでPassportをインストールします。

```
php artisan passport:install
```

下記のようなシークレットキーを作成してくれます。

```
Encryption keys generated successfully.
Personal access client created successfully.
Client ID: 1
Client secret: XXXXXXXXXXX
Password grant client created successfully.
Client ID: 2
Client secret: XXXXXXXXXXX
```

### Userモデルの変更

app\user.phpの編集

```
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Laravel\Passport\HasApiTokens; → 追加
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
```

```
class User extends Authenticatable
{
    use HasApiTokens,Notifiable; →　HasApiTokensの追加
```

### AuthServiceProviderの変更

app\Providers\AuthServiceProvider.phpの編集

    namespace App\Providers;
    use Laravel\Passport\Passport; ->  追加
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as 
    ServiceProvider;
    use Illuminate\Support\Facades\Gate;

    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',　→　コメントアウトを外す
    ];

    public function boot()
    {
        $this->registerPolicies();
        Passport::routes(); →　追加
        //
    }

### auth.phpの変更

app\config\auth.php

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

        'api' => [
            'driver' => 'passport', →　変更
            'provider' => 'users',
            // 'hash' => false,  →　削除
        ],
    ],
```

### 中間動作確認

下記のURLにアクセスして動作トップ画面がエラーなく表示されることを確認してください。  
もし、エラーが表示される場合は、前までの章を見直してください。

```
http://localhost:8080/
```

### routesの変更

routes/api.php

```
// Route::middleware('auth:api')->get('/user', function (Request $request) { → コメントアウト
//     return $request->user();　→ コメントアウト
// });　→ コメントアウト

Route::post('login', 'API\UserController@login');　→ 追加
Route::post('register', 'API\UserController@register');　→ 追加

// 下記のgroupの下には認証が必要
Route::group(['middleware' => 'auth:api'], function(){　→ 追加
    Route::post('details', 'API\UserController@details');　→ 追加
});
```


### ユーザ登録(Userコントローラーの作成)

下記のコマンドを実行しUserコントローラーを作成します。

```
php artisan make:controller api/UserController
```

app\Http\Controllers\api\UserController.php
上記のファイルにユーザ登録の機能を追加します。

```
<?php

namespace App\Http\Controllers\API;
use Illuminate\Http\Request; 
use App\Http\Controllers\Controller; 
use App\User; 
use Illuminate\Support\Facades\Auth; 
use Validator;

class UserController extends Controller
{
    public $successStatus = 200;
    //
/** 
     * Register api 
     * 
     * @return \Illuminate\Http\Response 
     */ 
    public function register(Request $request) 
    { 
        $validator = Validator::make($request->all(), [ 
            'name' => 'required', 
            'email' => 'required|email', 
            'password' => 'required', 
            'c_password' => 'required|same:password', 
        ]);
if ($validator->fails()) { 
            return response()->json(['error'=>$validator->errors()], 401);            
        }
$input = $request->all(); 
        $input['password'] = bcrypt($input['password']); 
        $user = User::create($input); 
        $success['token'] =  $user->createToken('MyApp')-> accessToken; 
        $success['name'] =  $user->name;
return response()->json(['success'=>$success], $this-> successStatus); 
    }
}
```

### ユーザ作成の確認

下記のURLを実行します。

```
http://localhost:8080/api/register
```

リクエストはPOSTです。

Bodyのfrom-dataとして下記のパラメータを渡します。

name  名前
email　メールアドレス
password　パスワード
c_password　パスワード（確認用)

Postmanで実施すると下記のようになります。
![スクリーンショット 2020-12-28 午後5.16.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/8ecf5577-a76c-ff15-3f86-a4a6a4de8f8b.png)

成功すると上記の画像のようにtokenが発行されます。

### ユーザ詳細(Userコントローラーの編集)

app\Http\Controllers\api\UserController.php
上記のファイルにユーザ編集の機能を追加します。

     /** 
     * details api 
     * 
     * @return \Illuminate\Http\Response 
     */ 
    public function details() 
    { 
        $user = Auth::user(); 
        return response()->json(['success' => $user], $this-> successStatus); 
    } 

### ユーザ詳細の確認

ユーザ詳細は、認証がないとアクセスできません。
そのため、ダイレクトでアクセスしても認証がないのでエラーになります。

```
http://localhost:8080/api/details
```

Bearer Tokenに、ユーザ登録で取得したTokenを貼り付けます。
リクエストはPOSTです。

![スクリーンショット 2020-12-28 午後5.28.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/4667bedf-abe9-7585-1431-0c74fd44e5bf.png)

Bodyにユーザ情報が返ってきたら正しく実装できた証拠です。

### ユーザログイン(Userコントローラーの編集)

app\Http\Controllers\api\UserController.php
上記のファイルにユーザログインの機能を追加します。

```
/** 
     * login api 
     * 
     * @return \Illuminate\Http\Response 
     */ 
    public function login(){ 
        if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){ 
            $user = Auth::user(); 
            $success['token'] =  $user->createToken('MyApp')-> accessToken; 
            return response()->json(['success' => $success], $this-> successStatus); 
        } 
        else{ 
            return response()->json(['error'=>'Unauthorised'], 401); 
        } 
    }
```

### ユーザログインの確認

```
http://localhost:8080/api/login
```
リクエストはPOSTです。

登録と同じemailとパスワードをform-dataとして指定します。

下記のようにログインが成功すると下記のレスポンスが返ります。

![スクリーンショット 2020-12-28 午後5.37.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282387/4e66de25-2b7c-801f-2ad6-6fd7cf1cb431.png)

### 終わり

上記の手順で完了です。

今回の記事のゴールを達成できました！
- ユーザを登録できる
- ログインしたらユーザ詳細を表示できる
- ログインできる

参考した方のgithubを貼り付けます。
https://github.com/anil-sidhu/laravel-passport-poc