Laravel5の認証にRole追加（同じテーブル編）


###やりたいこと

Laravelでは、はじめから認証機能が実装されています。が、標準機能だけでは間に合いません。
その１つに、role別の認証があります。認証用のテーブルを分けない方法と、分ける方法がありますが、ここでは、標準のusersテーブルにroleカラムを追加し、それにより認証を分けるやりかたをやってみます。

###基本設定など

標準で利用する限りは特に設定等は必要ありません。認証は標準でusersテーブル、User(.php)クラスを使うことのなっていますが、これは、config/auth.phpの中で定義されているので、必要に応じて変更します。

```php
<?php

return [

	'driver' => 'eloquent',

	'model' => 'App\User',

	'table' => 'users',

	'password' => [
		'email' => 'emails.password',
		'table' => 'password_resets',
		'expire' => 60,
	],

];
```

###usersテーブルの生成

usersテーブルは、手動で生成することもできますが、はじめからmigrationファイルがdatabase/migrationsの中にあるので、それを利用します。今回はroleを足します。ここにadminとかuserとかを保存し、認証時に利用します。

```php
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('users', function(Blueprint $table)
		{
			$table->increments('id');
			$table->string('name');
			$table->string('email')->unique();
			$table->string('password', 60);
			$table->string('role',16);
			$table->rememberToken();
			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('users');
	}

}
```

準備ができたらmigrateコマンドを実行する。

```
php artisan migrate
```

ひな形ファイルを作ったりするのは、

```
php artisan make:migration filename --create="tablename"
```

とすると、up()の中にSchema::create〜の入りのひな形を作ってくれます。

###ユーザー登録

Seederを使ってもいいですが、ここでは普通にroute.phpにユーザー追加のルートを記述します。
普通にname,email,passwordとroleを登録します。1つ注意が必要なのは、passwordはかならずハッシュ化しておかないと、リード時に読めません。

```php
Route::get('add',function(){

	//user
	$email = "hoge2@hoge.com";
	$name = "hoge2";
	$password = "password";
	$role = "admin";

	//hashing
	$password = Hash::make($password);

	//create user object
	$user = new \App\User;

	$user->email = $email;
	$user->name = $name;
	$user->password = $password;
	$user->role = $role;

	//save
	$user->save();

	echo "adding<br>";

	//login
	Auth::login($user);

	//get user info
	$login_user = Auth::user();

	//echo user info
	echo $login_user->name."<br>";
	echo $login_user->role."<br>";
});
```
ここでは、追加に加え、ログイン処理、ログインユーザー情報の取得も行っています。

>このコードをそのまま複数回実行すると、emailが重複するためユニーク属性に関するエラーが出ます。

###認証
認証自体はGurdクラスのattempt()メソッドで行います。通常の書式は、

```php
Route::get('login',function(){

	$email = "hoge2@hoge.com";
	$password = "password";

	if(Auth::attempt(['email'=>$email,'password'=>$password])){

		//ok
		return "login";

	}else{

		//ng
		return "login error";

	}

});
```
となります。これにroleを追加したいので、

```php
Route::get('login',function(){

	$email = "hoge2@hoge.com";
	$password = "password";

	if(Auth::attempt(['email'=>$email,'password'=>$password,'role'=>'user'])){

		//ok
		return "login<br>";

	}else{

		//ng
		return "login error";

	}

});
```
とします。'role'=>'admin'を足すことで、条件にadminを追加しています。
これにより、認証処理と、OKの場合はログイン処理が行われます。

なお、実際には、上記の$emailや$passwordは、POST等で受けた変数を設定します。

###ログイン

ログインは原則として上記、Auth::attempt()を利用します。
ユーザー情報（email,password）が取得できている場合は、

```php
$user = new User;

$user->email = $email;
$user->password = $password;
//$user->name = $name;

$auth->login($user);

```
と、ユーザーを指定してログインさせることもできます（但し、DB照会は行われないので、注意が必要です）。

ログインしたユーザーの情報は、

```php
$user = Auth::user();

echo $user->email;
echo $user->role;
```
として取得可能です。追加したrole等も反映されます。
ログイン状態のチェックは、

```php
Auth::check()
```
で、できます。

###ログアウト
ログハウとはlogout()で行います。

```php
Route::get('logout',function(){

	Auth::logout();

	return "logout";

});
```

###ミドルウエアでの利用

認証機能（adminだけ入れるようなページ）は、ミドルウエアで実装することになります。なので、ミドルウエアを新規に作るか、標準のapp/Http/Middleware/Authenticate.phpのコードをroleも見るように変更する必要があります。

ここではAuth::check()でログイン状態をチェックし、roleがadminかどうかを追加判断しています。

```php
if(\Auth::check()){

	if(\Auth::usr()->role=='admin'){
		//ログインしているかつ、role=adminの処理
	}else{
		//ログインエラー
	}
	
}else{

	//ログインエラー
	
}

return $next($request)
```

ミドルウエア自体の利用は、ルーティングでmiddlewareを指定するか、Controllerのコンストラクタ等で指定する。
なお、新規にmiddlewareを作った場合は、Kernel.phpの$routeMiddlewareに登録する必要があります。


###ルートでの利用

通常ミドルウエアはroute.php内で利用することになります。

####クロージャ
middlewareを指定してやる。使用するmiddlewareは、app/Http/Kernel.phpで指定されている。実態は、app/Http/Middlewareの中にある（作られる）。

```php
Route::('admin',['middleware'=>'auth',function(){
	//何か
	return "welcome admins";
}]);
```

####コントローラ
middlewareに加え、usesで資料するcontroller@methodを指定。

```php
Route::get('admin'['middeware'=>'auth','uses'=>'HogeController@admin']);
```

###コントローラでの認証

コントローラの頭で、指定することでも利用可能です。

```
class HogeController extends Controller{
	public function __construct(){
		$this->middleware('admin');
	}
}
```
などとする。

```
class HogeController extends Controller{
	public function __construct(){
		$this->middleware('admin',['except'=>'login']);
	}
}
```
などとして、例外も指定できる。login画面などはログインしてなくても見れる必要があるので。