はじめに
お仕事で、Zend Frameworkのバージョンアップをしなければならなくなった・・と思ったら、Zend Frameworkはもうなくて、Laminas Projectに移って新たなフレームワークとして公開されている。 しかし、Laminas MVCでは必要な要件を満たさないことが分かってとん挫していた。
そこで、次の候補としてLaravelを挙げて、必要な要件を満たせるかどうかを一歩ずつ調査していく。
要件(8)
8つ目の要件は、「カスタマイズされたユーザー認証手順での認証ができること」。
Zend Frameworkで言うところのZend_Authを使った独自認証機構。
渡されたユーザー名からテナントDBを特定して、(アルゴリズムは一般的だけど)独自のパスワードハッシュ関数を使って渡されたパスワードをハッシュ化して照合して、ログイン認証に成功したらセッションにユーザー情報を保持しておく、というような流れを一通り作っていく。
導入
こちらでセットアップした環境を(コピーして)使っていく。
私は以下のようにコピーを作成。
cp -pr laravel-setup-7-session-data laravel-setup-8-user-auth cd laravel-setup-8-user-auth
検証方針
すべてを真面目に組み上げると、パスワードのハッシュ関数なども実装しなければならなくなるので、ここでは流れだけを確認するために、以下のようなものを実装することにする。
- 認証時には以下のパラメータを渡す
- GETパラメータでテナントコード(tenant_code)を渡す
- GETパラメータでユーザー名(user_name)を渡す
- 渡されたテナントコードを元にテナントDBを特定する。特定できない場合は認証エラー
- 渡されたユーザー名を元に、特定されたテナントDB内に該当するユーザー名が存在するかを確認する。存在しなければ認証エラー
- 特定されたユーザーアカウントの識別子をセッション情報に保持する
- 検証用ページでは、以下のような表示をする
- ユーザー識別子がセッションになければ「未ログイン」と表示する
- ユーザー識別子がセッションに保存されていたら、テナントDBから取得できる実名(real_name)とともに「ログイン済み」と表示する
設定・実装
まず、コントローラーを以下のように作成する。
php artisan make:controller '\App\Http\Controllers\UserAuthController'
このapp/Http/Controllers/UserAuthController.phpを以下のように編集する。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Session; class UserAuthController extends Controller { public function index() { if (Session::has('user.userId') && Session::has('user.tenantCode')) { $tenantCode = Session::get('user.tenantCode'); $user = DB::connection('tenant-' . $tenantCode)->table('user_master') ->where('user_id', Session::get('user.userId'))->first(); $message = 'ログイン済み:' . $user->real_name; } else { $message = '未ログイン'; } return view('user-auth.index', ['message' => $message]); } public function login(Request $request) { $tenantCode = $request->get('tenant_code'); $userName = $request->get('user_name'); $user = DB::connection('tenant-' . $tenantCode)->table('user_master') ->where('user_name', $userName)->first(); Session::put('user.tenantCode', $request->get('tenant_code')); Session::put('user.userId', $user->id); return redirect('/user-auth'); } public function logout() { Session::forget('user.userId'); Session::forget('user.tenantCode'); return redirect('/user-auth'); } }
次に、ビューテンプレートresources/views/user-auth/index.tplを以下の内容で作成する。
{$message|escape:"html"}
最後に、routes/web.phpに以下を追記する。
Route::get('/user-auth', [\App\Http\Controllers\UserAuthController::class, 'index']);
Route::get('/user-auth/login', [\App\Http\Controllers\UserAuthController::class, 'login']);
Route::get('/user-auth/logout', [\App\Http\Controllers\UserAuthController::class, 'logout']);
動作確認
以下のURLにアクセスする。
http://<your-ip-address>/laravel-setup-8-user-auth/public/user-auth
最初は以下のような画面が表示されればOK。
未ログイン
次に、以下のURLにアクセスする。
http://<your-ip-address>/laravel-setup-8-user-auth/public/user-auth/login?tenant_code=0001&user_name=tenant0001
以下のような画面が表示されればOK。
ログイン済み:テナント1 太郎
まとめ
- セッションを使ってやりたいことは実現できた
- 本当は、存在しないユーザーなどのエラー処理をしなければならないのだけど、今回は割愛した