write ahead log

ロールフォワード用

Laravel標準の機能で認証フォームを作る

Homestead上のLaravel 5.7.4で試した.

Laravelには認証を実装するための機能が標準で付いてきています.

認証はどこでも必要になるので入門するには良いとっかかりということで, 利用してみました.

実装できる機能

標準でもこれだけ実装できます.

ほとんどのプロジェクトはこれで十分でしょう.

  • ユーザ登録
  • ログイン
  • ログアウト
  • パスワードリセット

プロジェクトの作成

Homesteadのデフォルトに合わせてcodeプロジェクトにしました.

$ composer create-project --prefer-dist laravel/laravel code

認証機能用コードのScaffolding

認証機能を使うには, まずはプロジェクトフォルダ直下で以下のコマンドを実行します.

$ php artisan make:auth

これだけで認証機能のベースになるコードが生成(Scaffolding)されます.

$ tree app/Http/Controllers
app/Http/Controllers/
├── Auth
│   ├── ForgotPasswordController.php
│   ├── LoginController.php
│   ├── RegisterController.php
│   ├── ResetPasswordController.php
│   └── VerificationController.php
├── Controller.php
└── HomeController.php

Authフォルダ以下とHomeController.phpが生成されています.

DBのマイグレーション

認証に使うユーザ情報はDBに保持します.

database/migrations以下を見ると先のコマンドで既にマイグレーションファイルが生成されています.

$ ls database/migrations/
2014_10_12_000000_create_users_table.php  2014_10_12_100000_create_password_resets_table.php

そのままマイグレーションします.

$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

実行してみる

なんと実装はこれだけで, トップページへアクセスしてみると既にナビゲーションバーにloginとregisterの項目ができています.

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

確認のために雑にページを作る

ログインしていないユーザがアクセスできないページが欲しいので, 雑にページを生成します.

PostsControllerを作ります.
(不要なアクションも含めresourceオプションで生成)

$ php artisan make:controller PostsController
Controller created successfully.

アクションを追加.

public function index()
{
    return view('posts.index');
}

public function create()
{
    return view('posts.create');
}

Postsのビューも用意して.

$ mkdir resources/views/posts
$ echo "index" > resources/views/posts/index.blade.php
$ echo "create" > resources/views/posts/create.blade.php

ルートも追加しておきます.

# routes/web.php
Route::get('/posts/', 'PostsController@index');
Route::get('/posts/create', 'PostsController@create');

認証による制御

ルートのフィルタ

ルートへのアクセスの可否を制御するには2つの方法があるっぽい.

ルート定義に記述

ルート定義にメソッドチェーンして, middleware('auth')を呼び出す.

# routes/web.php
Route::get('/posts/create', 'PostsController@create')->middleware('auth');
コントローラのコンストラクタに記述

ただし, この場合はコントローラのアクション全体に認証によるフィルタがかかる.

public function __construct()
{
    $this->middleware('auth');
}

認証済みか調べる

コントローラ内で簡単に調べられます.

use Illuminate\Support\Facades\Auth;

if (Auth::check() === true) {
    // ユーザーはログインしている
}

ログインユーザを調べる

use Illuminate\Support\Facades\Auth;

// ログインユーザーの取得
$user = Auth::user();

// ログインユーザーのIDを取得
$user_id = Auth::id();

ログイン後などのリダイレクト先の変更

デフォルトでは

/home

へリダイレクトされるが, カスタマイズできる.

app/Http/Controllers/Auth/

配下にある3つのコントローラの定義をそれぞれ変更すればよい.

  • LoginController
  • RegisterController
  • ResetPasswordController
# これを変える
protected $redirectTo = '/home';

ログアウトさせる

以下を呼び出す.

Auth::logout();

ビューを変える

resources/views/auth/にビューがあるので普通に変えればよいです.

多言語化

resources/lang/enに

  • auth.php
  • passwords.php

が出来ていました.

テスト

actingAsメソッドで認証できる.

public function testAccessSecurePage()
{
    $user = factory(App\User::class)->create();
    $response = $this->actingAs($user)
                     ->get('/posts/create');
    $response->assertStatus(200);
}

public function testDenySecurePage()
{
    $response = $this->get('/posts/create');
    $response->assertStatus(302);
}

参考

すごく良い翻訳ドキュメントがあった.

最初からこれを読めばよかった.

Github - laravel-ja/ja-docs-5.7

公式 - testing