A Laravel(Passport) - user000422/0 GitHub Wiki
概要
今なら読める https://supilog.supisupi.com/blog/jywu424ztuq4/
公式(Laravel 10): https://laravel.com/docs/11.x/passport ★★ 要注意ポイント ★★ 1台のサーバで検証する際はLaravelサーバを2つ起動すること。1つはデフォルトコマンド、2つ目はポート指定コマンド。
【かなり良い?】API認証(Passport)機能の動作確認 https://www.wakuwakubank.com/posts/457-laravel-passport/#index_id19 【ここもいい】Laravel 5.3 で Passportを試す https://blog.hinaloe.net/2016/09/15/try-passport-laravel-5-3/ PKCE https://qiita.com/okmt_okmt_/items/f70c7552b0ecba3375f6
Laravelアプリケーションに完全なOAuth2サーバー実装を数分で提供します。 Laravel Passportを実際に体験してみる https://qiita.com/miriwo/items/857ae5d156fcdec4c65a
PHP.iniの設定 … extension=sodium
sodiumがなければ … dnf install php-sodium
Grant種類 | 説明 |
---|---|
Password Grant | 今後廃止予定。ユーザー名とパスワードを直接使ってトークンを発行。 |
Authorization Code Grant | リダイレクトを通じてユーザーからの認可を得てトークンを発行 |
Client Credentials Grant | アプリケーション自体が自分のクレデンシャルを使ってトークンを取得 |
Refresh Tokens | 「アクセストークンの再発行」を行う。 |
テーブル | 説明 |
---|---|
oauth_clients | Client情報(clientuser, client secret)(client_idはidカラム) |
oauth_auth_codes | 認証コード(アクセストークンではない)が格納される |
oauth_access_tokens | アクセストークンが格納される |
oauth_auth_codesc |
リフレッシュトークン 初期有効時間 : 1年
認証認可の知識
一例)https://christina04.hatenablog.com/entry/secure-token-management 認可サーバ … トークンを発行するだけのサーバ リソースサーバ … 取得したいデータが格納されているサーバ アクセストークンでアクセス可
認証(ログイン)後、認可サーバからアクセストークンが発行される。 アクセストークンはログイン等のレスポンスでクライアントに渡され、Cookie(またはローカルストレージなど)に保存される。 リフレッシュトークンも同様。 トークンは一般的にはブラウザのCookieで管理するのが主流である。 Cookieには「httpOnly属性」をTrueにすること。JavaScriptからCookieの値を参照大対策。 ローカルストレージには保持しないこと。
プログラム
cd [Laravelプロジェクト]
# インストール
# Laravel10までのコマンド 11からは別コマンド
composer require laravel/passport
composer require laravel/passport:^12.2 # バージョン指定
composer require laravel/passport:^11.10 # バージョン指定
# マイグレーション
php artisan migrate
# 設定ファイル、トークンを作成するために使用する暗号化キー、クライアントの作成
# storageディレクトリの中にoauth-private.key, oauth-public.keyという名前でキーが保存されます。
php artisan passport:install
# Q.Would you like to run all pending database migrations?
# yes
# Q.Would you like to create the "personal access" and "password grant" clients?
# Q.「personal access client」と「password grant client」を作成しますか?
# yes
# Authorization Code Grantの場合のクライアントの作成
php artisan passport:client --public
■【必須 共通】モデル(ユーザテーブル)の編集
use Laravel\Passport\HasApiTokens; // パスをpassportに変更
class User extends Authenticatable
{
use Notifiable,HasApiTokens;
}
■AuthProvider.phpの編集
Laravel Passport11からは Passport::routes()
の記述は不要。(記述したらエラー)
■【必須 共通】config/auth.phpの編集
編集後クリアすること php artisan config:clear
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users', // 会員テーブル
],
],
■トークンを所持していない場合のリダイレクト先 ログイン画面のルートにnameを設定する。
// routes/web.php
Route::get('/login', [LoginController::class, 'index'])->name('login');
■【適切に設定】api.php ルーティングに対してAccessTokenによる認証ガードを設定。
//Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
Route::middleware('auth:api')->get('/sample', function (Request $request) {
return $request->user();
});
■【動作確認済み】認可画面をスキップしたい場合
# まずはモデルを作成
mkdir /var/www/html/sample-app/app/Models/Passport
php artisan make:model Passport/Client
// model 編集
// 参考 : 公式github https://github.com/laravel/passport/blob/12.x/src/Client.php
use Laravel\Passport\Client as BaseClient;
class Client extends BaseClient
{
public function skipsAuthorization(): bool
{
//return $this->firstParty();
return true; // こっちにしとけば変な事故起きない
}
}
■AuthServiceProvider
AuthServiceProvider
public function boot(): void
{
// 持続時間(Access Token)
Passport::tokensExpireIn(now()->addSeconds(3600));
}
■CORS設定(要確認)
参考 : x
config/cors.php
# 'paths' => ['api/*', 'sanctum/csrf-cookie'],
'paths' => ['api/*', 'sanctum/csrf-cookie', 'oauth/token/*'],
■Controller Password Grantの場合
// app/Providers/AppServiceProvider.php
// Passport 12 の場合は下記が必須
use Laravel\Passport\Passport;
public function boot(): void
{
Passport::enablePasswordGrant();
}
use Illuminate\Support\Facades\Auth;
public function store(Request $request)
{
// Auth::attempt ユーザテーブルでログイン認証(email, password)
// 早期リターン
if (!Auth::attempt($credentials)) {
// ログイン失敗。
}
$user = Auth::user();
// トークン作成(スコープなし)
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_in' => $tokenResult->token->expires_at->diffInSeconds(now()),
'refresh_token' => $tokenResult->token->id,
]);
}
ログアウト
■公式
use Laravel\Passport\TokenRepository;
use Laravel\Passport\RefreshTokenRepository;
$tokenRepository = app(TokenRepository::class);
$refreshTokenRepository = app(RefreshTokenRepository::class);
$tokenRepository->revokeAccessToken($tokenId);
$refreshTokenRepository->revokeRefreshTokensByAccessTokenId($tokenId);
■野良
$tokenIds = Passport::token()
->where('user_id', Auth::id())
->where('client_id', $clientId)
->where('revoked', false)
->get()
->pluck('id');
Passport::token()
->whereIn('id', $tokenIds)
->update(['revoked' => true]);
Passport::refreshToken()
->whereIn('access_token_id', $tokenIds)
->update(['revoked' => true]);
return response()->json();