5月 272014
 

こんにちは。ファガイです。

本日はlaravel4を使用した認証のチュートリアルです。
初めてそれっぽいチュートリアルを書くかもしれません。。。

確認環境

確認環境は以下となります。

  • Apache2
  • PHP 5.4
  • MariaDB
  • Laravel4.1

Laravelの導入

まずは、Laravelアプリケーションの導入をします。laravel.pharインストーラーでの作成が便利です。

laravel new auth_sample

storageをApacheからアクセスできるように権限の変更をします

cd auth_sample/app
chown -R apache:apache storage

app.phpのtimezone、locale、keyを変更します。

<?php
return array(
...
'timezone' => 'Asia/Tokyo',
...
'locale' => 'ja',
...
'key' => 'これは自分で決めて下さい'
...
);

DBの設定を行う

DBの設定を行います。こちらは人によりけりなので自分がやりやすい方法でDBの追加を行って下さい。

一応MySQL(MariaDB)の場合の例(ユーザ名root,パスワードpasswordの場合)

mysql -uroot -ppassword
CREATE DATABASE laravel_auth_sample;

database.phpのmysqlの部分を書き換えます。

'mysql' => array(
    'driver'    => 'mysql',
    'host'      => 'localhost',
    'database'  => 'laravel_auth_test',
    'username'  => 'root',
    'password'  => 'password',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
),

パッケージのrequireを行う

今回、Sentryを使用するためcomposer.jsonに追加記述をします。なお、私はide-helper等も入れましたがこれは省きます。

Sentryの導入方法に関しては公式サイトにも記載されているので、そちらも確認すると良いでしょう。

Sentry Manual :: Cartalyst

"require": {
    "laravel/framework": "4.1.*",
    "cartalyst/sentry": "2.1.*"
}

requireを記載したため、composer updateでアップデートを行います。

composer update

あとは、書いてある通り、app.phpの'providers'と'aliases'に以下を追加しましょう。

providers

'Cartalyst\Sentry\SentryServiceProvider',

aliases

'Sentry'  => 'Cartalyst\Sentry\Facades\Laravel\Sentry',

Sentryのテーブルを追加する

Sentryを使用する際に必要なテーブルが存在します。こちらを入れます。(マニュアルにも書かれています)

cd auth_sample
php artisan migrate --package=cartalyst/sentry

しっかりDB等の設定がされていれば問題なくテーブルが追加されます。

Configを有効化する

Configの設定をpublish化します。

php artisan config:publish cartalyst/sentry

このコマンドを打つことで、app/configフォルダのpackages内にこのパッケージ用のconfig.phpが作成されます。(コピーされます。)

今回は、このconfigは変更しません。
なので実際は不要な操作だと思われます。

よく分かってない補足

Laravelアプリケーションを作成した際に作られるUserモデルですが、今回使いません。
SentryのパッケージにUserモデルが存在するため追加メソッドを入れたい場合はそのモデルを継承する等した方が良いかな?名前空間が違うのでよく分からない。

アプリケーションの作成

ここまでで設定に関しては終了したので、ここから認証のサンプルアプリケーションを作っていきます。

今回この認証のアプリケーションを作るにあたり、参考にさせて頂いた物は以下となります。

Laravel 4 – Starter Kit – GitHub

今回はEmailとPasswordで認証する一般的なものを作成します。

なお、今回の目的は認証をすることなのでエラーを表示したり等、フロント側に関しては全くやっていません。

では、まず今回作成するものについて解説をします。

今回作成、変更するもの

追加するもの

  • AuthController.php – 認証用のコントローラです。記述はこれがメインです。
  • signup.blade.php – 登録画面を表示するテンプレートです
  • login.blade.php – ログイン画面を表示するテンプレートです
  • message.php – 認証失敗時に表示するメッセージを格納しているファイルです

変更するもの

  • BaseController.php – 一つだけメンバ変数の追加があります
  • route.php – ルーティングの追加をします
  • filter.php – ルーティングのフィルターを変更します

以上となります。
本当にフロントは最低限なので、全く意識してません。すみません。

ルーティングを行う

まずは、route.phpから作っていきます。ソースは以下です。

<?php
Route::get('/', array('as' => 'home', 'uses' => function()
{
    return View::make('hello');
}));

// ユーザ認証処理
Route::get('/user/signup', array('as' => 'signup', 'uses' => 'AuthController@showSignUp'));
Route::post('/user/signup', 'AuthController@execSignUp');
Route::get('/user/login', array('as' => 'login', 'uses' => 'AuthController@showLogin'));
Route::post('/user/login', 'AuthController@execLogin');

前回の記事で解説したasプロパティを今回使用しています。
asプロパティに関しては前回の記事の確認をお願いします。

LaravelのRouteで使用するasが非常に使える件 – 新人Webエンジニアの記録。

このroute.phpを見ると分かるかと思いますが、今回AuthControllerには4つのメソッドが存在します。サインアップの際の表示用と実行用と、ログインの際の表示用と実行用ですね。

Viewを作る

次に、Viewを作りましょう。非常に簡易的なものです。

viewsディレクトリ内に、authディレクトリを作りましょう。
その下にlogin.blade.phpとsignup.blade.phpを作って下さい。(今回は、bladeの恩恵は無いので通常のphpでも良いでしょう)

views/auth/signup.blade.php

<!doctype html>
<html lang="ja-JP">
<head>
    <meta charset="UTF-8">
    <title>登録</title>
</head>
<body>
<h1>登録</h1>
<form action="<?= URL::route('signup'); ?>" method="post">
    <label>Email:<input type="email" name="email" value=""></label><br>
    <label>Password:<input type="password" name="password" value=""></label><br>
    <input type="submit" value="登録"/>
</form>
</body>
</html>

views/auth/login.blade.php

<!doctype html>
<html lang="ja-JP">
<head>
    <meta charset="UTF-8">
    <title>ログイン</title>
</head>
<body>
<form action="<?= URL::route('login'); ?>" method="post">
    <label>Email:<input type="text" name="email"></label><br>
    <label>Password:<input type="password" name="password"></label><br>
    <input type="submit" value="ログイン">
</form>
</body>
</html>

はい。単にpostするだけの内容ですね。
URL::route('signup')やloginは、分かりますよね。対応したURLが取得できます。
実際、このactionの値は空でも良いでしょう。

コントローラーの作成

いよいよAuthControllerを作成するのですが、先にBaseControllerに以下を記述しておいて下さい。

controllers/BaseController.php

<?php

class BaseController extends Controller {

    /**
     * Message Bag
     * @var Illuminate\Support\MessageBag
     */
    protected $messageBag = null;

    public function __construct()
    {
        $this->messageBag = new Illuminate\Support\MessageBag();   
    }

以下省略    

このmessageBagは、エラーメッセージやOKメッセージなどを格納するためのクラスとなります。
リダイレクト等の際に使われるwithErrorメソッドの引数等で使用されています。

では、AuthControllerにとりかかりましょう。(下に解説入れます)

controllers/AuthController.php

<?php

class AuthController extends BaseController
{
    public function __construct()
    {
        parent::__construct();
    }

    // 登録をする画面
    public function showSignUp()
    {
        return View::make('auth/signup');
    }

    // 登録処理
    public function execSignUp()
    {
        $validation_rule = array(
            'email' => 'required|email|unique:users',
            'password' => 'required|min:4'
        );
        $validator = Validator::make(Input::all(), $validation_rule);

        // バリデーション判定
        if ($validator->fails())
        {
            // 失敗
            return Redirect::back()->withErrors($validator);
        }

        // 成功
        try{
            // ユーザーの追加
            Sentry::register(array(
                'email' => Input::get('email'),
                'password' => Input::get('password'),
            ), true);

            return Redirect::route('home');

        }catch(Exception $e) {
            // エラー
            $this->messageBag->add('all', Lang::get('auth/message.signup.error'));
        }

        return Redirect::back()->withInput()->withErrors($this->messageBag);
    }

    // ログイン画面
    public function showLogin()
    {
        return View::make('auth/login');
    }

    // ログイン処理
    public function execLogin()
    {
        $validation_rule = array(
            'email' => 'required|email',
            'password' => 'required'
        );
        $validator = Validator::make(Input::all(), $validation_rule);

        // バリデーション判定
        if ($validator->fails())
        {
            // 失敗
            return Redirect::back()->withInput()->withErrors($validator);
        }

        try{
            // 認証
            $user = Sentry::authenticate(Input::only('email','password'), Input::get('remember-me', 0));

            // 認証出来たのでリダイレクト
            return Redirect::route('home');

        } catch (Cartalyst\Sentry\Throttling\UserSuspendedException $e) {
            // 制限中
            $this->messageBag->add('all', Lang::get('auth/message.account_suspended'));
        } catch (Cartalyst\Sentry\Throttling\UserBannedException $e) {
            // バン
            $this->messageBag->add('all', Lang::get('auth/message.account_banned'));
        } catch (Exception $e) {
            // 他
            $this->messageBag->add('all', Lang::get('auth/message.login.error'));
        }

        return Redirect::back()->withInput()->withErrors($this->messageBag);
    }
}

突然ソースを出されても困りますね。

まず、show~メソッドに関しては分かるかと思います。ただ単に先程のViewの表示を行っているだけとなります。

exec~メソッドが実行用のメソッドになります。

まずは、execSignUpを見てみましょうか。

execSignUp

最初は、バリデーションのルールを設定しています。ルールを設定した後に、Validator::makeでインスタンスを作成します。

$validator->fails()でバリデーションが成功したか判定を行っており、失敗した場合は、Redirect::back()で前のページに戻ります。

成功した場合は、Sentry::registerメソッドを使い、ユーザーの追加を行った後、リダイレクトします。

失敗した場合は、Exceptionがあるため取得し、Lang::getでメッセージを取得してmessageBagに入れます。

その後に、Redirect::back()でその情報を返します。

execLogin

execLoginも同様です。
最初にバリデーションの判定を行い、問題なければ認証しリダイレクト。失敗すればmessageBagにメッセージを入れてます。

Lang::getで指定しているauth/message

先程説明をしていませんでしたが、Lang::getのauth/messageってどこにあるの?と思われたかもしれません。

これは、lang/ja/auth/message.phpを作る必要があります。(順番的にこちらの方が良いと思いました)

lang/ja/auth/message.php

<?php

return array(
    'account_already_exists'    => 'そのメールアドレスは既に使用されています',
    'account_not_found'         => 'そのアカウントは存在しません。',
    'account_not_activated'     => 'そのアカウントはアクティベートされていません。',
    'account_suspended'         => 'そのアカウントは制限中です。',
    'account_banned'            => 'そのアカウントは凍結されています。',

    'signup' => array(
        'error' => 'アカウントの作成に失敗しました。',
        'success' => 'アカウントの作成に成功しました。'
    ),

    'login' => array(
        'error' => 'ログインに失敗しました。',
        'success' => 'ログインに成功しました。'
    )
);

このファイルを作ることで、先程のLang::getでauth/messageが取得できますね。

filterを修正する

最後にfilterを修正しましょう。

filters.phpの'auth'フィルターを書き換えます。

filters.php

Route::filter('auth', function()
{
    if ( ! Sentry::check())
    {
        return Redirect::route('login');
    }
});

認証されてなければ、loginに飛ぶように変更しました。
これでOK。

まとめ

今回ですが、チュートリアル内で表示確認を行っていません。
ですので、例えばroute.phpなどでSentry::check()メソッドを実行し、ログイン中か、ログインしてないか等を確認してみるのも良いかと思います。

ではでは。

Pocket

 Posted by at 6:56 AM

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


*