さて、だいたい慣れてきた。折角なのでここからは与えられたサンプルコードを使わずに一から作っていこうと思う。
もちろんサンプルコードは参考にする。
とりあえず、プロジェクトの開始
すっかり忘れてしまったのだけど、.bashrcに
export COMPOSER_HOME=~/.composer export PATH=$PATH:~/bin:$COMPOSER_HOME/vendor/bin
と書き、~/.composer/composer.json に
{ "require": { "laravel/installer": "~1.1" } }
としているので、~/.composerにて $composer updateする。もちろん、~/bin/にcomposer.pharを入れている。すると、Laravel Installerによるlaravelコマンドが任意の場所で使える。
プロジェクトの作成
$ laravel new ~/laravel/auth_sample
でとりあえず、雛形作成。キー生成も済んでいる。
- require-devにfilp/whoopsを入れてcomposer update
- .envにデータベースの設定を行う。データベースの方も新しくDBを作っておく。
- Laravel5でDBのQueryログを出すEvent Listenerを作る - tohokuaikiのチラシの裏を入れる。
データベースの作成
作るテーブルの情報はP.158の表4.2と表4.3の通り。
マイグレーションの作成
usersテーブルを作るMigration
$ ./artisan make:migration create_user_table --create=users Created Migration: 2016_12_29_124332_create_user_table
password_resetsテーブルを作るMigration
$ ./artisan make:migration create_password_resets_table --create=password_resets [InvalidArgumentException] A CreatePasswordResetsTable migration already exists.
???あれ、既にある。
$ ls database/migrations/ 2014_10_12_000000_create_users_table.php 2014_10_12_100000_create_password_resets_table.php 2016_12_29_124332_create_user_table.php $ ./artisan make:migration create_users_table --create=users [InvalidArgumentException] A CreateUsersTable migration already exists.
あるじゃん・・・というか、usersテーブルもあるんだ。
ということで、さっき作った2016_12_29_124332_create_user_table.phpを削除して、composer dump-autoloadする。
マイグレーションの実行
$ ./artisan migrate Migration table created successfully. Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table $ mysql -u **** -p**** laravel_authsample -e "show tables" +------------------------------+ | Tables_in_laravel_authsample | +------------------------------+ | migrations | | password_resets | | users | +------------------------------+
作成完了。
Modelクラスを作る
$ ./artisan make:model User Model already exists!
・・・あれ、もうできてる。
認証機能の設定
コントローラの配置
書籍によると、
の2つが既にあるらしい。
5.3だとそれらは無いのだが、
- app/Http/Controllers/Auth/RegisterController.php
- app/Http/Controllers/Auth/ResetPasswordController.php
の2つがある。見た感じそれぞれが対応しそうである。
認証の設定
config/auth.php が本の5.1とは随分と異なっている。
肝心な部分はここだと思われる。
<?php 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
このままでおそらく本書と同じであろうからそのまま。
メッセージファイル
resources/lang/ja/passwords.php を作成。面倒なので、本書のサンプルコードをそのままコピー。
ルーティング
Routingを行う。
routes/web.php に
<?php Route::resource('/register', 'Auth\RegisterController');
を追加。
実装開始
とりあえず・・・
雛形のAuth\RegisterControllerは、Illuminate/Foundation/Auth/RegistersUsers をtraitしているのでこのクラスを使ってみる。
GET/indexを追加
<?php protected function index() { return $this->showRegistrationForm(); }
いきなりLaravel5.1と5.3での違いに戸惑う
で、次はpost周りを・・・と思ったけど Illuminate/Foundation/Auth/RegistersUsers.phpが5.1と5.3では大きく変わってる。
あれー、と思って調べるとHow to register a user in Laravel 5.3?で「Route::auth()」使うんやでっていうコメントが。
Illuminate/Routing/Router.php のauth()を見てみると、あー。。。なんか色々とRoutingしてくれている。
ということで、 routes/web.php を
<?php // Route::resource('/register', 'Auth\RegisterController'); Route::auth();
と変更。Auth\RegisterControllerに付け加えた protected function index()も削除。
findすると vendor/laravel/framework/src/Illuminate/Auth/Console/stubs/make/views/auth/register.stub なるスタブもある。
んんん~~。と思い、調べると、artisanにmake:authコマンドがある。
結局、make:authコマンドの実行がベスト
./resources/views/layouts/app.blade.php ./resources/views/auth/register.blade.php ./resources/views/auth/passwords/reset.blade.php ./resources/views/auth/passwords/email.blade.php ./resources/views/auth/login.blade.php ./resources/views/home.blade.php ./app/Http/Controllers/HomeController.php
が追加されていた。
routes/web.phpには以下の2行が追記されていた。もはや、Route::auth()メソッドですらない。
<?php Auth::routes(); Route::get('/home', 'HomeController@index');
Authの機能について
Authファサードでよく使いそうな機能について
Auth::attempt()
普通のHTTPの場合なので、実態は、Illuminate/Auth/SessionGuard.php
- 第1引数:usersテーブルに合致する情報の配列。ただし、passwordをキーに持つ値の場合はhasherによりHash化される。
- 第2引数:trueにすると自動ログ引用トークンを発行。そのトークンを持っているだけでログインできる。
- 第3引数:trueにすると認証が正当な場合にログイン処理を行う。
実際には、Illuminate/Foundation/Auth/AuthenticatesUsers.php のlogin()にて使われている。 これを直接使うのはあまり無いかも知れない。
Auth::check()
ログイン状態のチェックをする。guest()メソッドはこれの反転。Bladeテンプレートでも @if (Auth::guest()) とかで簡単に使える。
Auth::viaRemember()
Tokenによるログインを行ったかどうか。
セッションが切れてCookieのRememberトークンによるログインになった場合はこれがtrueになる。
Auth::user()
App\Userオブジェクトを返してくれる。
Controllerメソッド(あるいはRoutingの際のClosure)のTypeHinting
これ、どうやって実装してるんだろう・・・・。
Middlewareではなく、config/auth.phpで設定される何かから引っ張ってきているんだろうとは思うんだけど。
何となくこんな感じというのを調べてみた。 LaravelのメソッドのTypeHintがどうやってパラメータをうまい具合にセットしているのか? - tohokuaikiのチラシの裏
Illuminate\Http\RequestをTypeHintingに使うと、$request->user()でユーザー情報が取れる。
RoutingのClosureで使う場合
<?php use Illuminate\Http\Request; Route::get('/', function (Request $request) { dd($request->user()); return view('welcome'); });
Controllerメソッドで使う場合。
<?php use Illuminate\Http\Request; class HomeController extends Controller { /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index(Request $request) { dd($request->user()); return view('home'); }
Illuminate\Contracts\Auth\Authenticatable をTypeHintingに使うとApp\Userオブジェクトがそのまま入ってくる。
ただし、この場合は認証を通過していないと引数にnullが入ってしまい
Controller::index() must implement interface Illuminate\Contracts\Auth\Authenticatable, none given
のエラーが出てしまう。
従って、
<?php public function __construct() { $this->middleware('auth'); }
として、middlewareにてAuthチェックを行うなどする必要がある。
Auth::login() / Auth::loginUsingId()
どちらも任意のログインユーザーでログインする。テストを書く時に使う。
<?php Auth::login(new \App\User::find(1)); Auth::loginUsingId(1);
Auth::once()
1リクエスト内で有効なログイン状態を作る。それ以外はAuth::attempt()と同じ。