2011年8月10日

Codeigniterを使ってショッピングカートをゼロから作ってみよう。 # 4

前回フロントエンドとバックエンドを分けたので、そこに認証機能をつけます。




■ ユーザに関する考察
ショッピングカートにはサイトの管理者と登録ユーザという2種類のユーザがいると思います。
サイトを運営するのは個人であったり会社であったりしますが、管理者が1人じゃないこともあるでしょう。そう考えると登録ユーザ(お客さん)と管理ユーザはわけたほうが良いかもしれません。

そこで登録ユーザをCustomer、管理ユーザをUserと位置づけ開発を続けていきたいと思います。


■ Usersテーブル作成
まず管理ユーザ用のDBテーブルを作成します。
(とりあえず現在のところは最低限必要な情報で構成しています。)

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `firstname` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `lastname` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `status` tinyint(4) NOT NULL,
  `role` int(11) NOT NULL,
  `hash` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `lastlogin` timestamp NULL DEFAULT NULL,
  `updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;



■ Authライブラリ作成
Codeigniterでは有名(?)なDX Authなどのライブラリの使用も考慮しましたが、結局どれを使っても用途に合わせてカスタマイズしないといけないので自作します。
△要件△
- メールアドレスとパスワードで認証。ユーザ名は別途考慮。
- パスワード暗号化
- UserとCustomerの別認証

/extension/libraries/Auth.php
<?php
class Auth
{
    var $_error;

    public function __construct()
    {
        $this->ci =& get_instance();
    }
        
    function error()
    {
        return $this->_error;
    }
    
    function login($email, $passwd, $target='customer')
    {
        if($target === 'user')
        {   // load user model
            $this->ci->load->model('users_model','usersdb');
            // check if exists
            if($user = $this->ci->usersdb->exist($email))
            {   // retrieve user hash & matching up with entered password
                if($this->_encode($passwd, $user->hash) === $user->password)
                {   // update last login
                    $this->ci->usersdb->lastlogin($user->id);
                    // set admin session
                    $this->ci->session->set_userdata('admin',TRUE);
                    
                    return TRUE;
                }
                else $this->_error = _l('error_wrong_combination');
            }
            else $this->_error = _l('error_not_exist');
        }
        
        return FALSE;
    }
    
    private function _encode($passwd, $hash)
    {
        /* 暗号化スクリプト */
        
        return $passwd;
    }
}

/extension/models/users_model.php
<?php
class Users_model extends Model
{
    var $table = 'users';
    
    function __construct()
    {
        parent::__construct();
    }
    
    function exist($email)
    {
        $q = $this->db->get_where($this->table, array('email'=>$email));
        return ($q->num_rows() == 1) ? $q->row() : FALSE;
    }
    
    function lastlogin($id)
    {
        $this->db->where('id',$id);
        $this->db->update($this->table, array('lastlogin'=>date('Y-m-d H:i:s')));
    }
}



パスワードはユーザごとにハッシュを作成し、一定の法則で入力パスワードとマッチングさせてます。
法則は_encodeメソッド内に好きなように指定してください。
ユーザごとのハッシュは登録時に作成しないといけないので、それは次回に。

とりあえずのところ認証ライブラリ(Auth)はできたので、テストユーザを直接DBに作ってテストしてみます。

DBにテストユーザ追加
INSERT INTO `users` (`id`, `email`, `password`, `firstname`, `lastname`, `status`, `role`, `hash`, `lastlogin`, `updated`) VALUES
(1, 'test@test.com', '723e66f900dcb555d089050c80455331feb2b7ca', 'firstname', 'lastname', 0, 0, '5898e88516d636dbd3571c7d24550f67', '2011-08-04 10:49:04', '2011-08-04 10:49:04');


■ autoload変更
認証でデータベース、およびセッションを使うようになるのでconfig/autoload.phpを以下のように変更します。
$autoload['libraries'] = array('Auth','database','Form_validation','Session');


■ コントローラ
admin/application/controllers/login.php
<?php
class Login extends Controller
{
    function __construct()
    {
        parent::__construct();
        if(_s('admin')) redirect();
    }
    
    function index()
    {
        $this->form_validation->set_rules('email',_l('EMAIL'),'required|trim|valid_email');
        $this->form_validation->set_rules('password', _l('PASSWORD'), 'required|trim');
        if($this->form_validation->run())
        {
            $login = $this->auth->login($this->input->post('email'), $this->input->post('password'), 'user');
            if($login)  redirect();
            else $data['error'] = $this->auth->error();
        }
        else $data['error'] = validation_errors();
        
        $data['css'] = array('login');
        $data['page_title'] = _l('CONTROLPANEL');
        $this->layout->view('login', $data);
    }
}


■ ビュー
admin/application/view/login.php
<?php echo form_open(uri_string()); ?>
<div>
<h1><?php echo _l('CONTROLPANEL'); ?></h1>
<p><?php echo _l('MSG_LOGIN'); ?></p>
<dl>
    <dt><?php echo _l('EMAIL'); ?></dt>
    <dd><input type="email" name="email" value="<?php echo set_value('email'); ?>" /></dd>
    <dt><?php echo _l('PASSWORD'); ?></dt>
    <dd><input type="password" name="password" value="" /></dd>
    <dd><input type="submit" value="<?php echo _l('LOGIN'); ?>"></dd>
    <?php if(isset($error)): ?><dd><?php echo $error; ?></dd><?php endif; ?>
</dl>
</div>
<?php echo form_close(); ?>

これで準備は完了です。


■ログイン画面
どうせだったらと簡単にデザインしてみました。デザインは苦手なんですよねー(^_^;;



上で追加したユーザでログインしてみます。


うん、ちゃんと admin セッションが登録されていますね。
ログインした時に登録するべきセッションは admin だけではないですが、それは必要に応じて追加して行きたいと思います。


次回はユーザ登録をやります。

0 件のコメント:

コメントを投稿