Lumen で認証を扱い始めたばかりのころ、キーワードで Google を検索する以外に、いちばんよくやるのが公式の Authentication ドキュメントを開くことだと思います。そして僕と同じように、期待して開いて、結局よく分からないまま閉じることになります。Laravel の経験がないまま Lumen に触れた人にとって、このドキュメントは省略が多すぎて、まるで手がかりがありません。
認証のしくみ全体を詳しく説明する前に、まずはこの短い一枚の Authentication ドキュメントが結局何を言っているのかを、ざっくり説明します。
Authentication Service Provider
いまや DI(Dependency Injection)が当たり前の時代で、サービスを使う前にまず登録するのは、多くの PHP 開発者にとって反射のようなものになっています。ところが、公式の Authentication ドキュメントどおりに AuthServiceProvider を登録し終えたあと、次の段落を見て固まってしまう人が多いはずです。この意味のよく分からないコードは、いったいどこから出てきたのでしょう?
$this->app['auth']->viaRequest('api', function ($request) {
// Return User or null...
});
どの単語も分かる気がするのに、なんだかしっくり来ません。たしかに、これが AuthServiceProvider の boot メソッドの中に書かれていて、サービスの起動時に動くコードだということは分かります。でも、具体的には何をしているのでしょう?
まあ、待ってください。焦らずに、いったん視点を引いて、大きな疑問はわきに置きましょう。公式の Authentication ドキュメント全体が説明している流れを、かみくだいて言うと、だいたいこんな感じです:
- システムに 認証サービス を登録する。
- サービスの起動時に、リクエストをチェックする門番 を用意する。
- そのチェックの途中で、ユーザーを見分ける必要があれば、返却用のユーザーオブジェクト を用意できる。
- 認証ミドルウェア(auth middleware)の中で、用意しておいた 門番 を呼び出して認証チェックを行う。
ここではまず、よくある疑問を簡単な Q&A の形で答えていきます。詳しい中身と流れは、後の記事で説明します。
Authentication ドキュメント Q&A
viaRequest 関数はどこから来たの?リクエストをチェックするという意味?
そうとも言えるし、そうでないとも言えます。コードのコメントから見ると、viaRequest は via Request というより via RequestGuard、つまり リクエストの門番 RequestGuard を通してリクエストを処理する、という意味に近いです。viaRequest を呼び出すと、RequestGuard を作るための関数が 登録 されます。実際の RequestGuard オブジェクトが作られるのは、その Guard が初めて解決(resolve)されるときで、それまでは作られません(この点は後の記事で詳しく説明します)。
viaRequest('api', …) の api って…?
この api は、いま作っている API とは直接関係ありません。カスタマイズできる auth driver のキーで、理屈のうえでは好きな文字列に置き換えられます。ただし、config/auth.php 側も合わせて変更するのを忘れないでください。
viaRequest(…, callback) の後ろの callback って…?
ここでの callback は、ユーザーオブジェクトを返す ための関数です。公式ドキュメントのこの構成では、返されたユーザーオブジェクトには 2 つの役割があります:
- RequestGuard が、入ってきたリクエストを ユーザー として解決するのか、それとも ゲスト 扱いにするのかを判断できるようにする(null を返すとゲストとみなされます)。
$request->user()を呼び出したときに、この関数が動いて ユーザーオブジェクト を取得する。
app['auth'] はどこから来るの?
ご存じのとおり、ServiceProvider の中の $this->app は Lumen Application オブジェクトそのものです。そして app['auth'] は、アクセスされたときに自動で生成される AuthManager オブジェクトです。先に app['auth'] へアクセスしていないかぎり、ここが初めてインスタンス化される場所のはずです。試しに、このコードの前後で isset($this->app['auth']) を書いて確かめてみてください。
では $this->app['auth']->viaRequest('api', callback) という一行全体の意味は?
かんたんに言うと、AuthServiceProvider が起動するとき、自動で作られた AuthManager を通じて RequestGuard の auth driver を登録し、そこに ユーザーを判定して、ユーザーオブジェクトを取得する ための callback を渡している、ということです。
実際に認証を行っているコードは、いったいどこにあるの?
公式の Authentication ドキュメントの構成では、2 か所あります。1 つめは、Authenticate Middleware の handle 関数の中です:
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
ここでは Guard(デフォルトの api Guard)を呼び出して、リクエストがゲストかどうかを判断し、そうであればアクセスを拒否します。
2 つめは、AuthServiceProvider の boot メソッドの中です:
$this->app['auth']->viaRequest('api', function ($request) {
// Return User or null...
});
ここで定義した ユーザーオブジェクトを返す callback が null を返すと、guard($guard)->guest() が true になります —— ゲストとみなされてアクセスが拒否されます。逆に、ユーザーを返せば、リクエストはそのまま通ります。
おわりに
この記事が、公式の Authentication ドキュメントを理解する助けになったなら、僕としてはとても嬉しいです。もしまだ疑問が解けなくても、大丈夫です。これからの記事で、認証のしくみ全体をできるかぎり詳しく解きほぐしていきます。そのころには、また少し違う見方をお届けできればと思います。


