LoginSignup
11
10

More than 5 years have passed since last update.

Laravel 5.7 Oauthサーバの実装

Last updated at Posted at 2018-09-28

API認証の実装

Laravel 5.7でOAuthを用いた認証の実装の備忘録。
https://readouble.com/laravel/5.7/ja/passport.html

Laravel Passportを使ってみます。
このライブラリはOAuthサーバーとして有名なleague上に構築されているとのこと。
https://oauth2.thephpleague.com/

なお、Laravelのインストールとデフォルトのユーザー認証構築済みの前提。

インストール

composerでインストール

composer require laravel/passport

client, accessTokenを格納するテーブル作成

php artisan migrate

accessToken生成のためのキーを作成

php artisan passport:install

Userモデルへ、traitの追加。

User.php
namespace App;

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

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;

AuthServiceProviderへメソッドを追加。
AccessTokenの発行・失効をこれで管理するよう。
/oauth/authorizeなど一通り使えるURLがこれで設定されるとのこと。

AuthServiceProvider.php

use Laravel\Passport\Passport;

public function boot()
{
  Passport::routes();
}

設定ファイルで、認証APIリクエストの方式を変更。

config/auth.php
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

APIテスト

APIのテストをしてみます。
ひとまず今はパスワードグラントのテスト。

Chrome addonのRestlet Client が便利でした。
https://chrome.google.com/webstore/detail/restlet-client-rest-api-t/aejoelaoggembcahagimdiliamlcdmfm

まずは、/register でユーザー登録をしておきます。

次にクライアントを登録。
grant typeはpasswordとなるので、以下の様に生成。

php artisan passport:client --password

成功すると、ID&secretが表示される。

Password grant client created successfully.
Client ID: 2
Client Secret: r5V5xoKmBrU2kOmG4ZOrF0iCcJ4lfVncTvWnRk2P

Request Token

アクセストークンを取得する。
トークンの有効期間は、AuthServiceProvider で設定した内容となる。

Method: POST
URL: youredomein.com/oauth/token
Header: [Content-Type: application/json;]
body:

{
    "grant_type": "password",
    "client_id": 2,
    "client_secret": "r5V5xoKmBrU2kOmG4ZOrF0iCcJ4lfVncTvWnRk2P",
    "username": "my.name@mail.com",
    "password": "test",
    "scope": "*"
}

Result:

{
"token_type": "Bearer",
"expires_in": 1296000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjgwYjU2MWQyZDkyNDYyMTFjMTEwZjRhZTBlMGU1NjhjMTE5M2FmMTg4YWE1YTNlYmEzNzdkMGMyMzdmYzhiYjNmYTY0NmRkZGQwZWUxZWJiIn0.eyJhdWQiOiI2IiwianRpIjoiODBiNTYxZDJkOTI0NjIxMWMxMTBmNGFlMGUwZTU2OGMxMTkzYWYxODhhYTVhM2ViYTM3N2QwYzIzN2ZjOGJiM2ZhNjQ2ZGRkZDBlZTFlYmIiLCJpYXQiOjE1MzgxMjMzNDMsIm5iZiI6MTUzODEyMzM0MywiZXhwIjoxNTM5NDE5MzQzLCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.YC1eGzgFzdKtOrIhz2a6mlGeGIwKEC3Fdn2edmC4NWmujT09kLCRz2yKykpS_sgZkOUV34FQyZxU2Wh3CXd89Bdqk2x-Vn_w3sggw2GbJMkkFY_pLFdUpFXdUJoNBE-tExvL4wPSQy9kmwgY0KP5Ufpg25y8g5jG9Nog2AnJihA_iRI-f07JpLGIcYO1xmXwyPZMT1JsDe_BKjqH4CQLOkMHI9JtMdr8Sghrg5uoOoFdfDcRT2Sm8AvMNcQ-NIdG6vLApY2hsOAPEXhc0XBIE6qjERwP1gtg0qZq0hIGY3fWKKo7q935M9CpBd-TRIQHSGcMdkBoSpLAnRla0avUqzkj3Mwkw6OvK6CPdB80rRU9cPU5Z1p3Ta6kCSL74PwLs3dTXgLdXxY-W6k3SBc9KbLWRkojcmxHYGKzfuYn4Ax3EQc0JXfwch0qTlP5OPeWRnBlGE147tla5Gyp6wobB8oTo3GYFh4TnRiF-fleMF4dUStp_0f8swo3jlrynhydzUPXhtgH2pRGKqsWNPgyPpZrGkUYgUfWrfQw1hxjNMDD_w61HyNgk5vCPfJgioBkOUqKkbVXvuGliMiOirFPptizkktXfHLBo_1eP2glruWmicg35ajwIxCmN7NcbiSszR96ZOmCCrJYlok5yiMtbdvY9YCiwTCu8W5E5HXZAT8",
"refresh_token": "def502006646396ea837409159a9869ef64072f2d3ae436d2c91746ed0ec72f72cb6721c03c2e48d165f2e76f8b3fec4a5e78c46d9fb25686a5200aa8699138d52a25cd03ab0d922a2bec8432430e2bfd94881c8bb663ab5e41cf1dddf0c9ff31ff277e950ebe51559c6ee9db53546fbd481cbc6f4814a664d0eca7e6508cb1b2e7530bb9dfbc908ceda042c4b31d2a6d577d70bc3dba5e5b7c903a5a2e85f9116b6505121f3c4395765494305caf01b612063bce17debfcacc30bc34f357f7fc9edf9a9836fba1ef8c5bad676eb937e81e74c313944fc4b8ef815b2d65258884dcf20104afad7cd25182763cb6979b64d5f17b011da4b27926289061590d8ace5b9a5d869ee42504a5e91348ac1ec5bd56c76dc7e71a3c83ae9c5db36e1bbff28aded4fd8439e81215d284e72b784fabd9e3a8db0d48da70532e97da2febbd32df02e3b48d08d088693263a23634a185c11dce0712594a3c00bd4ddb134a705639e06fa"
}

expires_inは、tokenが無効になるまでの秒数とのこと。
AuthServiceProviderクラスのboot()で指定可能。

AuthServiceProvider
        Passport::tokensExpireIn(now()->addDays(15));
        Passport::refreshTokensExpireIn(now()->addDays(30));

※ただし認証時に正しくチェックされないとの情報あり(未検証)

Get user information

次にユーザー情報を取得してみます。
ヘッダーのAuthorizationで、アクセストークンを渡します。

Method: Get
URL: youredomein.com/api/user
Header: [Accept => application/json,
Authorization => Bearer xxxxxxxxxxxxxxxxx]

Result:

{
"id": 1,
"name": "My Name",
"email": "my.name@mail.com",
"email_verified_at": null,
"created_at": "2018-00-00 00:00:00",
"updated_at": "2018-00-00 00:00:00"
}

Refresh token

Tokenのリフレッシュです。

Method: POST
URL: youredomein.com/oauth/token
Header: [Content-Type: application/json;]
body:

{
    "grant_type": "refresh_token",
    "refresh_token": "def50200c2111621e18b14a7a065ea75eeaa004fe07c25b20bb78e382f9b06843e7c3c9e41d5b23b3883f9ef646432a685734efc4022c88163512ef8242b289730763c6aaca2ab541eef807b2b704b440a76696f337e20a28bc8f3618045076ecf4335b5ba08a7361a4f467ebb917208848815af1e6717faaa0e330907754e3b823afea6657e4acfbf62cde5f4991bbc6fb40e1985f55d1bf665867e7db3aa087a1242654bea511008fcc1730525026ae0736c498ca96f656acde5757da0c9124559b29f68a6aa6914cdc33360826b0e07bdd9bcd09d963238e8c537b75afd17a27c28db5d51432453452d26c6c2f4d61276ed1176dff1fd3acb6a0462f6f0da1cb802442b32d615e7ec2a14b463a524bc51e6c33069ec879e72683f9c98931c36a14ece4dd74d4d44a4def2f7e2e208a8d47672dce019c66ef4847643d669b7c5796899f7465000ffbd998f196caf47095e00c3cb310c43784dc154e7ce1c51c54c3b43",
    "client_id": 2,
    "client_secret": "r5V5xoKmBrU2kOmG4ZOrF0iCcJ4lfVncTvWnRk2P",
    "scope": "*"
}

Result:

{
"token_type": "Bearer",
"expires_in": 1296000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjAyNWNmZGE2ZDNjZjQ1NTUyMjc1YzI1ZjI4MWJkZWZiMmZhMTY1MmMyNThlMDdhYmY0NWE4ZDdiZTdjN2UxOWY0NDBiNWIyMGQ4NzJiMmQyIn0.eyJhdWQiOiI2IiwianRpIjoiMDI1Y2ZkYTZkM2NmNDU1NTIyNzVjMjVmMjgxYmRlZmIyZmExNjUyYzI1OGUwN2FiZjQ1YThkN2JlN2M3ZTE5ZjQ0MGI1YjIwZDg3MmIyZDIiLCJpYXQiOjE1MzgxMjY1OTUsIm5iZiI6MTUzODEyNjU5NSwiZXhwIjoxNTM5NDIyNTk1LCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.KxT_L3q8-kuq8Jhz6YjljWjJb90OObbpPJ_vYNkPRWR7Rho0kFvtiVgbjwKTfxFWYaFENpw3nDI8r1kCTn50UWRPz3NyeFCu8Q7BiXAigq-gsDJ5HpqQZs21JdvGkC7SNR00yGq7ij6rIsdDvnSN6g08zzacx0gpX3fMAQ60Wa3qrcc14SQWecG2zI7PrxVn_9vuxOMtChNMDJvg1vIytteOzdoE2RS_ITxYEpoTYlm4sB0Fjq6X81Llu7lT8oE8YQRHcUrf1CyyT_C-hQfbmC1r_ZcHK6H6vqzefEZ5O8lceY15J-klZXdbwlkCcSADpFkg_Ssu9cRlVEmHK19URgcb6DTLYWVgw0P9Mqbsr2QBCqaaUTHon1vsflZ9cq_cKqZ_lMYK9GsnwNn-GeZoB83WIGNVMbiY6t3rtWaf-HPkS0Y0WUe6FUA7FomKHkHyhXHQhqH_wDgU1lgazLWTn9zO87FWCZxWvkpgf3qQSS_QYPFeiJzmNb_s6StxKU77QqP6duhA9JSrBBzSVwxivRdXFCHmGMqG9meKfKE5_geLcP_NEhEydsCxvvNa5pfPW7FqpjgI4s1w8XWg1y6dK1Htjn5uBUdJY8ZhEOKuF8X-xq6GVuWJrUFsebAw5AQ1FGJI7_HxetJhNsVvsO4nP1nYSs4M44Wxgo1VR439vXM",
"refresh_token": "def50200c668fc733991b8cb84378b048f97a03fcee9bbf049ba18c8f468721f2e18c3c42e60bf9dd35c144114738393ce2552a9824da39f4f04bb7e778243339e71571468917689ee90bb7130a1e87f0cc52def018aca568578597a0521e2b061e5f6e62e3de8b97bfc93134459941125537a10337df917df9313faf3bc17fc038682068e8ed714d97390a9b18e34425134c1f250c724102579c55db637c0df0753bcf27c2fc2f94335cbd03827f78f5f1281cbf6d5f9ef5a2da01ec0c9737584741324582ec33ba1da4c0c1d31c3fc3eab8e7b9e21cf4c6b243259a73e5ed0e0ecef23738a1b9c639b94940750ee5526787a5e265e3e0daef589706c150264b0a1a6d2f67578b04018339b1689864ec4a4c9ee4c156669c97e4cae6f244b56b3fe516ae404315a07d97f0afd939899b5ea51d6038e8d83415572d849d5a7a944a861daa82b6f6a22e824fde67b6930498a20fb441961d07d190c0f9bb16bc964a5ef0f"
}

ほぼマニュアルからの抜粋ですが、以前cakephpで実装したときより格段に早く実装出来たと感じます。
次回は認可画面まで作りたいと思います。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10