カテゴリー : Laravel

Laravel 4 認証とメール送信のための設定について

Laravel 4 を学習するのにちょうど良いサンプルがあったので、ソースを追いながら設定やらフレームワークの機能などいろいろと突っ込んで調べてみました。もし同じように「チュートリアルになるサンプル」を探していたら一度ご覧下さい。

Laravel 4 Bootstrap :: L4 starter project with Twitter Bootstrap 2.2

このプログラムはフロントエンドからのユーザー登録とログイン認証、及びログイン後のユーザー情報の変更処理を扱ったプロジェクトで、フロントエンド表示に Twitter Bootstrap を利用しています。

Bootstrapは12カラムのグリッドシステムを採用したCSSフレームワークで、最近3.0へバージョンアップされ、機能も大変充実しています。Bootstrapの学習には百式管理人さんが制作された「Bootstrap 3.0入門」が秀逸です。

自分はアプリケーション開発でいつも管理画面に困っていましたが、CSSフレームワークがいくつも公開されており、それらを利用して開発することでますますスピードが早くなるように思います。

その他のフレームワークがブログ「Cats who Code」で紹介されています。

パスワードのリマインダー機能

Laravel 4 にはパスワードを忘れたユーザーがパスワードをリセットする際の「リマインダー機能」が組み込まれていることを知り、このチュートリアルで組み込んでみました。

その際、今後役に立ちそうな内容でしたので設定ファイルを備忘録として残しておくことにしました。

なお、リマインダー機能を利用するためartisanを使ってパスワードリマインダー用のトークンを保存するテーブルを定義しますが、GitHubからダウンロードしてComposerでインストールしたこのプロジェクトでは、「artisan auth:reminders」が利用できません。原因は、app/config/app.phpで指定されている「’providers’」に抜けがあるためで、Laravel 4 を普通にインストールした場合のものと比較すれば分かります。

リマインダーの設定(app/config/auth.php)

'reminder' => array(
    'email' => 'emails.auth.reminder',
    'table' => 'password_reminders',
    'expire' => 10,
),

「email」項目はパスワードをリセットする際の送信メールのテンプレートで、「app/views/emails/auth/reminder.blade.php」ファイルになる。メールはHTMLメールだが、プレーンテキストを利用したい場合、

    'email' => array('text' => 'emails.auth.reminder'),

とし、reminder.blade.php にHTMLタグを含めなければ良い。

「expire」項目は分単位で、パスワードリセットできるメール送信後からの有効期限を示す。デフォルトは60分らしい(未確認)。

メール送信の設定(app/config/mail.php)

Laravel 4 ではメール送信にSwift Mailerが利用されるとのことだが、Swift Mailerの詳細は調べていない。Coreserverを利用している自分は、SSLを利用したメール送信ができた。その設定は次の通り。

return array(
    'driver' => 'smtp',
    'host' => 'mxx-coreserver-jp.value-domain.com',
    'port' => 465,
    'from' => array(
        'address' => 'mt-systems@mt-systems.jp',
        'name' => '有限会社エムティシステム',
    ),
    'encryption' => 'ssl',
    'username' => 'username',
    'password' => 'password',
);

今後、セッションを利用したエラー表示についてもう少し知る必要がありそうだ。

 

Laravel 4 バージョンを確認するには?

ComposerでダウンロードしたLaravelのバージョンはいくつだったかな?と、思って確認する方法を調べてみた。

一番簡単な方法はLaravelをインストールしたディレクトリで次のように入力すればOK。

$ php artisan --version

または、ブラウザで確認する方法として routes.php に次のようにすると表示できる。

Route::any('version', function()
{
    $laravel = app();
    return "Current Laravel Version: " . $laravel::VERSION;
});

参考:How to determine the version of Laravel?

 

Laravel3 テーブルのカラム追加

Code Happy のブログチュートリアルに取り掛かるにあたって、新たに users テーブルをマイグレーションで作成する解説となっているのだが、以前マイグレーションの説明で users テーブルを作成していたので、これを利用しようかと考えた。

チュートリアルで作成するブログ「WordPre…」ではなく「Wordpush」では、以前の users テーブルに新しく「nickname」カラムを追加する必要がある。で、次のSQLとなるよなプログラムはどう書けばいいのか調べた。

ALTER TABLE users ADD COLUMN nickname varchar(128) NOT NULL AFTER username;

が、どうやら綺麗に書く方法はないようだ。そこでフォーラムの「Add column in table and migrate afterwards?」を参考に以下のようにしてみた。

先ず新しく「$ php artisan migrate:make add_users」でマイグレーションのテンプレートを生成して、次のようにプログラムした。

<?php
class Add_Users {
    public function up()
    {
        DB::query('ALTER TABLE users ADD nickname VARCHAR(128) NOT NULL AFTER username');
    }

    public function down()
    {
        Schema::table('users', function($table) {
            $table->drop_column('nickname');
        });
    }
}

見ての通りあまり美しくないけど仕方ないか。

実行は「$ php artisan migrate」、戻すときは「$ php artisan migrate:rollback」。

なお、新しい Laravel 4 ではできそうな感じです。取り付いたら試してみようかと。多分次のように書くのではないかな?と。

Schema::add('users', function($table) {
    $table->string('nickname', 128)->after('username');
});

まだよくわかりませんが。

Laravel3 データベースを使わない簡易認証

CakePHP以外のフレームワークを、と思っていくつか手を出したけど利用するところまで到達できない状態でした。ですがLaravelを習い始めてみると何となくイケそうな気がします。で、折角ですので備忘録も兼ねてブログに残そうかと思います。

Laravelの取り付きには、川瀬さんが翻訳されて出版されている電子書籍 Code Happy(JP) が良いかと思います。このネタもCode Happyの説明を利用したものです。以下「である調」で記述します。

小さなWebアプリで認証管理にユーザー登録機能を用意するのは、大した作業ではないが管理画面の処理も用意しなければならないので面倒だ。管理者1,2人程度ならプログラムに埋め込んで認証できればお手軽で良い。Laravelでは、認証の仕組みを利用して簡単に実現できた。

先ずは動きを見るための、外堀のプログラムから。

サイトのURLを「http://www.example.com」とし、「http://www.example.com/home」はログインユーザーのみ公開されているとする。ログインしていない状態で「home」を表示しようとするとログイン画面にリダイレクトされる。

LaravelはフレームワークなのでMVCのアプリケーションを組めるが、routes.php を利用してRESTfulなアプリケーションが組めるようになっており、オートロードの機能もありクラスを柔軟に活用できる。

home をアクセスしたとき homeビューを表示するプログラムは次の通り。

application/routes.php

Route::get('home', function() {
    return View::make('home');
});

簡単な homeビューを用意する。

application/views/home.blade.php

<div class="header">
    ようこそ!<br />
    {{ HTML::link('logout', 'ログアウト') }}
</div>
<div class="content">
    <h1>管理画面トップ</h1>
    <p>データベースを使わない簡易認証のページです。</p>
</div>

これだけで home にアクセスするとビューが表示される。

次はログインフォームのビュー。

application/views/login.blade.php

{{ Form::open('login') }}
    @if (Session::has('login_errors'))
        <span class="error">ログインエラー</span>
    @endif
    <p>{{ Form::label('username', 'ユーザー名:') }}
       {{ Form::text('username') }}</p>
    <p>{{ Form::label('password', 'パスワード:') }}
       {{ Form::password', 'パスワード' }}</p>
    <p>{{ Form::submit('ログイン') }}</p>
{{ Form::close() }}

で、ログイン画面の表示と送信されたログインデータを処理するプログラムの用意。どちらも routes.php 内で動作するように以下を追加。

application/routes.php

Route::get('login', function() {
    return View::make('Login');
});

Route::post('login', function() {
    return 'ログイン送信';
});

とりあえず、「http://www.example.com/login」でログインフォームの表示を確認し、ログインボタンを押すと「ログイン送信」が表示されるか確認する。

次に、home がアクセスされた時ログインチェックをして未ログインならログインフォームへ移行するようにする。これは、「Route::get(‘home’, …」で、処理をする前に認証チェックのフィルタプログラムを実行するように、次のように書き換える。

application/routes.php

Route::get('home', array('before' => 'auth', 'do' => function() {
    return View::make('home');
}));

そしてフィルタ「auth」をroutes.phpに追加する。が、「auth」フィルタは通常次のように routes.php に組み込まれている。

application/routes.php

Route::filter('auth', function()
{
    if (Auth::guest()) return Redirect::to('login');
}));

Auth::guest() はログインされていなければ true を戻す。Auth::check() はログインされていると true を戻す。

では、http://www.example.com/home へアクセスするとリダイレクトするか確認する。

いよいよLaravelの認証の仕組みを利用して簡易認証する手順に入る。

簡易認証のプログラムの内容は簡単で、usernameとpasswordを受け取り、プログラム内に書き込んだユーザー名とパスワードに一致するかどうかを判定するだけだ。なお、Laravelの仕組みに合わせるため認証プログラムは「Laravel\Auth\Drivers\Driver」から派生させ、認証メソッド「attempt()」とログインユーザーデータを戻すメソッド「retrieve()」を準備する。ファイルは「application/libraries/myauth.php」とする。これでオートロードされる。

application/libraries/myauth.php

<?php
class Myauth extends Laravel\Auth\Drivers\Driver
{
    private static $auth_users = array(
        array('id' => 1, 'username' => 'admin', 'password' => 'admin',
        array('id' => 2, 'username' => 'root', 'password' => 'root',
    );

    public function attempt($arguments = array())
    {
        $username = $arguments['username'];
        $password = $arguments['password'];

        foreach (self::$auth_users as $user) {
            if ($user['username'] == $username)
             && $user['password'] == $password) {
                return $this->login($user['id'],
                    array_get($arguments, 'remember'));
            }
        }

        return false;
    }

    public function retrieve($id)
    {
        foreach (self::$auth_users as $user) {
            if ($user['id'] == $id) {
                $data = new stdClass();
                $data->id = $user['id'];
                $data->username = $user['username'];
                $data->password = $user['password'];
                return $data;
            }
        }

        return null;
    }
}

Laravelで認証をどのように実行するかについての設定が「application/config/auth.php」にある。この中で、myauthを利用する設定とデータのusernameの項目名が何かの設定の2つ、変更しなければならない。

application/config/auth.php

'dirver' => 'myauth',
'username' => 'username',

そしてこれを使用することをAuthクラスに登録するため、「application/start.php」に次のように追加する(ファイルの最後に追加)。

Auth::extend('myauth', function() {
    return new Myauth();
});

ところで、ログインデータが送信されたときこのプログラムでユーザーを確認し、認証がOKならhomeへリダイレクトし、認証が失敗した場合はログイン画面へ戻るようにする部分を先の「Route::post(‘login’,…」に組み込む。合わせてログアウトするとログイン画面へリダイレクトする機能も実装する。いずれも routes.php 上である。

application/routes.php

Route::post('login', function() {
    $userdata = array(
        'username' => Input::get('username'),
        'password' => Input::get('password'),
    );

    if (Auth::attempt($userdata)) {
        return Redirect::to('home');
    }

    return Redirect::to('login')
        ->with('login_errors', true);
});

Route::get('logout', function() {
    Auth::logout();
    return Reidrect::to('login');
});

最後に、実際にログインして表示できた時「ようこそ、xxさん!」と表示するように、home.blade.phpビューを次のように変更しておく。

application/views/home.blade.php

:
ようこそ、{{ Auth::user()->username }}さん!<br />
:

動作するのを見て、Laravel 使いやすいな、と思った。

ところで、「application/config/session.php」にセッションデータのソースを操作するドライバの指定がある。この中で「’driver’ => ‘cookie’,」となっている部分を「’driver’ => ‘file’,」に変更するとセッションデータが、「storage/sessions」に書き込まれるようになる。

 

Laravel3 データベースのキャラクターセット

PHPのフレームワークLaravelが気になったので、電子書籍「Code Happy」を購入し、バージョン3を試している。

いよいよデータベースを使い始めるところで、テーブルusersをartisanを利用して生成したところ、何とdefault charset が ujis になっていた。これはレンタルサーバーのMySQLの設定で、default charsetがujisになっているためなのだろう。

フレームワークならSQLを書かなくてもテーブルが生成できるので、クラスのメソッドに何か仕掛けがあるに違いない、と思い込んで探したけれど残念ながら見つからなかった。

だからと言って、charsetのために丸々CREATE文を書くのも癪に障る。

そこでSSHでmysqlを起動し、直接データベースをutf8に設定する。

mysql -h xxx.db.sakura.ne.jp -u xxx -p xxx
mysql> alter database xxx default character set utf8;

で、artisan migrate を実行したところ、無事utf8のテーブルができた。

そこで一歩進めて「DB::query()」で上のalter文をプログラムに組み込んだところ、今度は「This command is not supported in the prepared statement protocol yet」とエラー表示され、正常に動作しない。

あー、もう、ガッカリだ。また今度何か対策を考えよう。