Laravel5.3ではOAuth2をベースとしたPassportを使用してLaravel5.5でAuth認証を実装する方法をサンプルコードを交えて詳しく紹介しています。友達が必要な場合は参考にしてください。皆さんのお役に立てれば幸いです。
はじめに
最近フロントエンドとバックエンドを分離するプロジェクトを書いています。本来はJwt-auth + Dingoを使って開発したかったのですが、少し面倒だったのでLaravelのことを考えました。 5.5 のパスポートと新しい API リソース。 Laravel Passport はパッケージ化された OAuth2 サーバー実装です
OAuth は認証のためのオープンネットワーク標準であり、現在のバージョンはバージョン 2.0 です。
OAuth 2.0 は現在一般的なアプローチであり、Google、Yahoo、Microsoft、Facebook などによって最初に使用されました。なぜ 2.0 とマークされているかというと、もともと 1.0 プロトコルがあったのですが、この 1.0 プロトコルは作りが複雑すぎて使いにくく、普及しなかったからです。 2.0 はシンプルで明確なプロトコルを備えた新しい設計ですが、1.0 と互換性がなく、1.0 とは何の関係もありません。
なので、ここでは詳細は説明しませんが、最初にインストール方法を見てみましょう。
インストール
パスポートをインストール
1. シェルで次のコマンドを実行します
composer require laravel/passport
使用しているLaravelバージョンが5.5未満の場合は、次の手順を実行する必要があります。手動で構成/ app.php ファイルのプロバイダー配列に次のコードを追加します
Laravel\Passport\PassportServiceProvider::class,
2. 移行ファイルを実行します
シェルで次のコマンドを実行します
php artisan migrate
パスポートサービスプロバイダーが使用するフレームワーク自体が移行ディレクトリに登録されるため、サービスを登録した後、PHP の移行を直接実行して、Passport に必要なデータ テーブルを生成できます
3. 暗号化キーを生成します
シェルで次のコマンドを実行します
php artisan passport:install
このコマンドは、安全なアクセス トークンの生成に必要な暗号化キーを作成します。同時に、このコマンドは、アクセス トークンの生成に使用される「個人アクセス」クライアントと「パスワード認証」も作成します。
4. Trait の追加
LaravelPassportHasApiTokens Trait を AppUser モデル
<?php namespace App; use Laravel\Passport\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasApiTokens, Notifiable; }
に追加します。 機能。
Passport::routes
class AuthServiceProvider extends ServiceProvider { public function boot() { $this->registerPolicies(); Passport::routes(); } }
プログラムでマルチプラットフォーム認証ではなく、フロントエンドとバックエンドの分離 OAuth 認証が必要な場合は、routers() メソッドで匿名関数を渡して、登録する必要があるルートをカスタマイズできます。これは、フロントエンドとバックエンドを分離する認証形式であるため、フロントエンド クライアントの 1 つに Auth 認証を提供するだけで済みます。そのため、トークンを取得するためのルートを登録するだけで、カスタマイズも行いましたそのプレフィックス名。
Passport::routes(function(RouteRegistrar $router) { $router->forAccessTokens(); },['prefix' => 'api/oauth']);
設定ファイルconfig/auth.php内の認可されたガードGuardsのAPIのドライバーオプションをパスポートに変更します。この調整により、アプリケーションは受信 API リクエストを検証するときに Passport の TokenGuard を使用できるようになります
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],
この時点で、残りのドキュメントで説明されているフロントエンド部分については、必要な作業のみがインストールされています。これを Auth 認証に使用し、完全な OAuth 機能を実装する必要はありません。フロントエンド ページを使用する必要はまったくありません。
を使用して、APIがデータを返すのを容易にするために、いくつかの関数をカプセル化しました
function respond($status, $respond) { return response()->json(['status' => $status, is_string($respond) ? 'message' : 'data' => $respond]); } function succeed($respond = 'Request success!') { return respond(true, $respond); } function failed($respond = 'Request failed!') { return respond(false, $respond); }
respond関数は基本的な戻りを実行でき、成功と失敗はリクエストを返すためのresponse関数で再カプセル化されます成功データとリクエスト失敗データ。
次に、プロキシのレイヤーを使用する必要があります。
まず、プロキシを使用する理由について説明します。パスポート認証のプロセスは、スレーブ アプリケーションがメイン アプリケーションによって生成されたクライアント トークンと、ユーザーが入力したアカウント パスワードを取得して、パスポート トークン ルートを要求することです。メインアプリケーションでアクセストークン(カード)とリフレッシュトークン(リフレッシュトークン)を取得すると、取得したアクセストークンでauth:api配下のルートにアクセスできるようになります。ただし、フロントエンドとバックエンドを分離するフロントエンドがありません。このアクセストークンをフロントエンドから取得したい場合は、フロントエンドにクライアントトークンを書き込む必要があります。非常に不合理なので、内部でプロキシを作成し、アプリケーション自体がクライアント トークンを使用してアクセス トークンを取得するように要求することができます。これは少し混乱するかもしれませんが、リクエストのプロセスはおそらく次のとおりです
1。ユーザーが入力したアカウント パスワードを使用してサーバーに要求します
2. サーバーはフロントエンドからアカウント番号とパスワードを受け取り、それに Client_id と Client_token を追加し、これらのパラメーターを使用して独自の Passport 認証ルートを要求し、返します。認証されたアクセストークンとリフレッシュトークン
下面是代码实现,我在 AppHttpControllersTraits 下新建了一个 ProxyHelpers 的 Trait,当然,这个函数是我根据我的业务逻辑自己封装的,如果不适合你的业务逻辑你可以自行调整。
<?php namespace App\Http\Controllers\Traits; use GuzzleHttp\Client; use App\Exceptions\UnauthorizedException; use GuzzleHttp\Exception\RequestException; trait ProxyHelpers { public function authenticate() { $client = new Client(); try { $url = request()->root() . '/api/oauth/token'; $params = array_merge(config('passport.proxy'), [ 'username' => request('email'), 'password' => request('password'), ]); $respond = $client->request('POST', $url, ['form_params' => $params]); } catch (RequestException $exception) { throw new UnauthorizedException('请求失败,服务器错误'); } if ($respond->getStatusCode() !== 401) { return json_decode($respond->getBody()->getContents(), true); } throw new UnauthorizedException('账号或密码错误'); } }
config/passport.php 内容如下
<?php return [ 'proxy' => [ 'grant_type' => env('OAUTH_GRANT_TYPE'), 'client_id' => env('OAUTH_CLIENT_ID'), 'client_secret' => env('OAUTH_CLIENT_SECRET'), 'scope' => env('OAUTH_SCOPE', '*'), ], ];
env 文件内容如下
OAUTH_GRANT_TYPE=password OAUTH_CLIENT_ID=2 OAUTH_CLIENT_SECRET=2HaTQJF33Sx98HjcKDiSVWZjrhVYGgkHGP8XLG1O OAUTH_SCOPE=*
我们需要用到的 client token 是 id 为 2 的 client token,不要搞错了哟~
然后我们只需要在控制器中 use 这个 Trait,然后调用 $this->authenticate()
就可以得到认证成功的 token,如果请求失败的话,你可以使用 catch 来捕捉错误抛出异常。
public function login(Request $request) { $needs = $this->validate($request, rules('login')); $user = User::where('email', $needs['email'])->first(); if (!$user) { throw new UnauthorizedException('此用户不存在'); } $tokens = $this->authenticate(); return succeed(['token' => $tokens, 'user' => new UserResource($user)]); }
得到的 tokens 返回如以下格式
{ "token_type": "Bearer", "expires_in": 31536000, "access_token": "token_str", "refresh_token": "token_str" }
做完这一切后你就可以在前端向这样子请求服务端了
axios.post('yourdomain/login',login_form).then(resource => { })
如果请求成功,那么你将会得到 用户的信息和 access token,refresh token。
然后在你的前端 http 请求 header 里需要加入一个参数 Authorization
axios.defaults.headers.common['Authorization'] = token.token_type + ' ' + token.access_token
然后在你需要使用到 auth 认证的路由里使用中间件 auth:api,一切就大功告成啦~
相关推荐:
Laravel5.5中的Package Auto Discovery详情介绍
以上がLaravel5.5でPassportを使ったAuth認証を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。