メインメニュー
XAMPP アレンジ
IED
WSL2
-
道具箱
リポジトリ編
フレームワーク編
公開ソフトウェア
メタ
リンク
- PHP ライブラリ
- PHP 言語
apricot:usage:ja:authentication目次
Apricot ユーザ認証
— y2sunlight 2020-09-03
目次
- Apricot ユーザ認証
Apricotでは次の2つのユーザ認証をサポートしています。
- 基本認証 — HTTPで定義される認証方法
- セッション認証 — ログイン画面による認証で、ログイン状態をセッションで管理する方式
セッション認証ではRemember-Meトークンによる自動ログインもサポートしています。
これらのユーザ認証の基盤はApricotコアに含まれています。Apricotのスケルトンではこの基盤を使って認証用のミドルウェアとコントローラーを実装しています。本章では、スケルトンでの認証に関する設定方法を示し、セッション認証用のミドルウェアとコントローラーの作成方法を説明します。
ユーザ認証の設定
認証方法の設定
スケルトンでは、ユーザ認証用のミドルウェアとして、基本認証とセッション認証の2つが用意されています。ミドルウェアの設定は、アプリケーションの設定ファイル
app.php
で行います。初期設定では、ユーザ認証にはセッション認証が使用されています。/your-project/config
- app.php
<?php return [ // ... 'middleware' =>[ \App\Middleware\Auth\SessionAuth::class, /* Session authentication */ ], // ... ];
ユーザ認証を基本認証に変更する場合は、ミドルウェアを以下のように変更して下さい。
- app.php
'middleware' =>[ \App\Middleware\Auth\BasicAuth::class, /* Basic authentication */ ],
基本認証はWebサーバの機能を使ったログインページを作る必要のない認証方法です。比較的小規模で簡易的なアプリケーションの場合に選択することができます。
ユーザ認証の設定
ユーザ認証の設定は、アプリケーションの設定ファイル(app.php)内の
auth
要素で行います。/your-project/config
- app.php
<?php return [ // ... 'auth' =>[ 'db'=>[ 'user'=>[ 'account' =>'account', 'password' =>'password', 'remember' =>'remember_token', ], ], 'expires_sec'=> 2*7*24*3600, /* 2weekws */ 'menu'=> true, ], ];
auth.db
要素には以下のデータベースの設定を行います。- user — テーブル名
- account — アカウントのカラム名
- password — パスワードのカラム名
- remember — RememberMeトークンのカラム名
上の例では、
user
テーブルのaccount
とpassword
カラムを使ってユーザ認証しています。また、RememberMeトークン保存用のカラムはremember
です。必要に応じてテーブル名及びカラム名は変更できます。ここで指定したテーブル名が認証用のユーザモデルになります。その他に以下のがあります。
- auth.expires_sec — RememberMeトークンクッキーの保存期間を秒単位で指定
- auth.menu — ページの左上にユーザメニューを表示するか否か設定(デフォルト値:false)
認証用のユーザモデルの作成
ユーザ認証の設定には、
Authenticatable
インターフェースを実装したユーザモデルを作る事が必要です。このモデルのデータベース情報を、前項で説明したapp.php
のauth.db
要素 に設定して下さい。Apricotのスケルトンでは認証用のユーザモデルとしてUser
クラスを作っています。/your-project/config
- User.php
namespace App\Models; use App\Foundation\Model; use ORM; use Apricot\Foundation\Security\Authenticatable; use App\Foundation\Security\AuthTrait; /** * User Model */ class User extends Model implements Authenticatable { /** * Includeing default implementation of Authenticatable interface. */ use AuthTrait; // ... }
AuthTrait
にはAuthenticatable
インターフェースが実装されています( 実際にapp.php
のauth.db
要素 を使っているのはAuthTrait
です)。 従って、AuthTrait
を use するだけで、それ以上のコーディングは不要です。
AuthUserクラス
AuthUserクラスは、Apricot コアの Authentication クラスをシングルトンにしたもので、全てのユーザ認証機能のこのクラスに集約されています。
AuthUserクラスでは以下のメソッドが使用できます。これらのメソッドは、主にミドルウェアと認証コントローラによって使用されますが、getUser()メソッドは様々な所から呼び出される可能性があります。
使用法: AuthUser::{メソッド}
メソッド 機能 authenticate
(string $account, string $password,
bool $remenber=false):boolユーザの認証を行い、成功の場合trueを返します。
(アカウントとパスワードで認証します)remember():bool ユーザの自動認証を行い、成功の場合trueを返します。
(RememberMeトークンによる自動ログインで使用します)check():bool ユーザが認証されているか否かを返します。 verify():bool ユーザが認証されているか否かを返します。
認証されている場合、ログインユーザ情報の更新を行います。forget() ログインセッションを削除します。 getUser():object ログインユーザを返します。 getPathAfterLogin():string ログイン後のURLパスを返します。
AuthUserクラスの実装
Apricotのスケルトンでは、以下のように
AuthUser
クラスが実装されています。/your-project/app/Foundation/Security
- AuthUser.php
<?php namespace App\Foundation\Security; use Core\Foundation\Singleton; use Core\Foundation\Security\Authentication; use App\Models\User; class AuthUser extends Singleton { /** * Create user authentication instance. * @return \Core\Foundation\Security\Authentication */ protected static function createInstance() { return new Authentication(new User()); } }
createInstance()
では、ユーザモデル( User )を使って、Authentication
クラスのシングルトンを生成しています。同様の方法で別のユーザモデルを使用したAuthentication
クラスのシングルトンも同時に作る事ができます。例えば、Userとは別に、AdminUser クラスや ApiUser クラスを使用した認証などが考えられます。このように、Apricotのスケルトンでは潜在的にマルチ認証を想定した実装ができるように配慮しています。但し、マルチ認証を行う場合は、ミドルウェアと認証コントローラを追加またはカスタマイズする必要があります。
ミドルウェア
セッション認証
セッション認証のミドルウェアは、
/App/Middleware/Auth/SessionAuth
です。他のミドルウェアと同様に、middlewareインターフェースの process() メソッドを実装し、その中で認証処理を行っています。以下に、
SessionAuth
ミドルウェアがどのようにAuthUserクラスを使って認証処理を実行しているのかについて説明します。/your-project/app/Middleware/Auth
- SessionAuth.php
/** * Middleware - Session authentication */ class SessionAuth implements Middleware { /** * @var array List of controllers to exclude */ private $exclude = [ 'AuthController', ]; /** * {@inheritDoc} * @see \Apricot\Foundation\Middleware\Middleware::invoke() */ public function process(Invoker $next): Response { // When excluded controller. if (in_array(controllerName(), $this->exclude)) { return $next->invoke(); } // Verifys whether user is authenticated. if (AuthUser::verify()) { return $next->invoke(); } // Redirect to login page If not authenticated. return redirect(route('login')); } }
$this->exclude 配列に含まれているコントローラは認証から除外します。通常は、ここには認証コントローラ( 上例では
AuthController
)が含まれます。他には、公開のページやWebAPIなどが含まれます。AuthUser::verify()
でユーザが認証されているか否かを調べ、認証されていれば次の処理に制御を渡します。まだユーザ認証されていない場合は、ヘルパー関数 redirect() を呼び出してログインページ画面にリダイレクトします。ミドルウェアでは、認証のチェックに
AuthUser::check()
ではなくて、AuthUser::verify()
を使用するのは、後者のメソッドがログインユーザ情報の更新を行うからです。これによってAuthUser
は常に最新のログインユーザ情報を保持することができます。
基本認証
基本認証のミドルウェアは、
/App/Middleware/Auth/BasicAuth
です。このクラスは以下に配置されていますので、必要に応じて参照して下さい。/your-project/app/Middleware/Auth/BasicAuth.php
認証コントローラ
セッション認証を使用した場合の認証コントローラについて説明します。Airpcotのスケルトンでは、認証コントローラとして
App\Controllers\AuthController
を提供しています。ルーティング
AuthController
のルーティングは以下のように定義されています。/your-project/config
- routes.php
$r->get ('/login', 'AuthController@showForm'); $r->post('/login', 'AuthController@login'); $r->get ('/logout', 'AuthController@logout');
- /login (GET) — ログインページ表示
- /login (POST) — ログイン処理 ( ユーザ認証 )
- /logout — ログアウト処理
AuthControllerクラス
セッション認証ではログインページから入力されるユーザアカウントとパスワードでユーザを認証します。また、ログイン時に、ブラウザ終了後もログイン状態を保持するか否かのチェック( Remember-Me )を行うことができます。
これらの処理は、
AuthController
クラスによって実行されます。以下に、このクラスのアクションがどのようにAuthUserクラスを使ってどのように認証処理を実行しているのかについて説明します。showFormアクション
public function showForm() { if (AuthUser::check()) { // Redirects to the top page if authenticated return redirect(route('')); } if (AuthUser::remember()) { // Redirects to the top page display if automatic authentication is possible return redirect(route('')); } return render('login'); }
AuthUser::check()
でユーザが認証されているか否かのチェックを行い、成功の場合は、ヘルパー関数 redirect() でトップ画面にリダイレクトします。一方、
AuthUser::check()
が失敗した場合は、AuthUser::remember()
で自動ログインを試みます。これが成功した場合は、トップ画面にリダイレクトします。ユーザセッションもなく、自動ログインにも失敗した場合、コントローラーはログインページをレンダリングします。
loginアクション
public function login() { $inputs = Input::all(); if (!AuthUser::authenticate($inputs['account'], $inputs['password'], !empty($inputs['remember']))) { // If the user cannot be found $errorBag = new ErrorBag([__('auth.login.error.no_account')]); return redirect(back())->withInputs()->withErrors($errorBag); } // When login is successful return redirect(AuthUser::getPathAfterLogin()); }
TODO:まず、Input::all()でログインページから入力変数を取得します。そして、それらの変数をパラメータにして
AuthUser::authenticate()
でユーザ認証を行います。認証に成功した場合、AuthUser::getPathAfterLogin()
でログイン後のに遷移するページのパスを取得して、そこにリダイレクトします。認証に失敗した場合は、withInputs()で入力変数を、withErrors()でバリデーションのエラーバッグを、それぞれのフラッシュ変数に保存し、ログインページにリダイレクトします。
logoutアクション
public function logout() { // Destroys the session AuthUser::forget(); // Redirects to the login page return redirect(route("login")); }
AuthUser::forget()
で認証セッションを破棄し、ログインページにリダイレクトします。
コアのユーザ認証機能
Apricotのコアで提供するユーザ認証機能を以下に示します。これらは、アプリケーションのモデルやデータベースに依存しない基本的なもので、ミドルウェアや認証コントローラーなどで使用されます。
- Authenticatable インターフェース — 認証されるユーザモデルが持つべきインターフェース
- Authentication クラス — ユーザ認証機能を持ったクラス
Authenticatableインターフェース
Apricotコアのユーザ認証機能を使用するには、
Authenticatable
インターフェースを実装したモデルを作成する必要があります。完全修飾名 :
Apricot\Foundation\Security\Authenticatable
メソッド 機能 getAuthName():string 認証を識別できる任意の名前を返します。
通常は認証のモデルとなるテーブル名を返します。(例:user)authenticateUser
(string $account, string $password)
:object|boolユーザの認証を行います。
成功の場合ユーザオブジェクトを返し、他は false を返します。
(通常はアカウントとパスワードによる認証を行います)remember
(string $remenber_token)
:object|boolユーザのRemnber-Meトークンによる認証を行います。
成功の場合ユーザオブジェクトを返し、他は false を返します。
(RememberMeトークンによる自動ログインで使用します)retrieveUser(object $user)
:object|boolユーザオブジェクトの再検索を行います。
成功の場合ユーザオブジェクトを返し、他は false を返します。
再検索のキーは引数 $user のアカウントが使えます。saveRemenberToken
(object $user, string $remenber_token)
:boolユーザのRemnber-Meトークンを保存します。
保存時のキーは引数 $user のアカウントが使えます。Apricotのスケルトンでは、
Authenticatable
インターフェースを実装したAuthTrait
を使用することができるので、そちらを利用して下さい:/your-project/app/Foundation/Security/AuthTrait.php
Authenticationクラス
Authenticationクラスはユーザ認証を行う全ての機能を持っています。通常、このクラスは、ミドルウェアと認証コントローラで使用されます。
完全修飾名 :
Apricot\Foundation\Security\Authentication
メソッド 機能 __construct
(Authenticatable $auth)Authenticationのコンストラクタ
生成時にAuthenticatableインターフェースを与えます。authenticate
(string $account, string $password,
bool $remenber=false):boolユーザの認証を行い、成功の場合trueを返します。
(アカウントとパスワードで認証します)remember():bool ユーザの自動認証を行い、成功の場合trueを返します。
(RememberMeトークンによる自動ログインで使用します)check():bool ユーザが認証されているか否かを返します。 verify():bool ユーザが認証されているか否かを返します。
認証されている場合、ログインユーザ情報の更新を行います。forget() ログインセッションを削除します。 getUser():object ログインユーザを返します。 getPathAfterLogin():string ログイン後のURLパスを返します。 本クラスは基本的にセッション認証用に作られていますが、基本認証の場合も authenticate()、verify()、getUser()メソッドは使用できます(基本認証の認証ページはブラウザによって提供され、ログアウトという考え方はなく、セッションとログイン状態は常に一致します)。また、check() と verify() は似たようなメソッドですが、check()はコントローラのアクションで、verify()はミドルウェアでの使用を想定しています。
apricot/usage/ja/authentication.txt · 最終更新: 2020/09/08 21:28 by y2sunlight
コメント