4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FuelPHPでSimpleauthを利用してアカウント登録機能を作る

Posted at

新規登録機能の実装

FuelphpのAuthパッケージというものを利用して、新規登録の認証機能を作ってみました。
実装ではAuthパッケージにおける「Simpleauth」というものを使いました。
開発環境は以下の通りです。

  • PHP 7.3
  • FuelPHP 1.8.2
  • MAMP

ここではざっくり以下を目標に機能の実装を行っていきます。

  1. パスワード確認用フォームの作成
  2. エラーメッセージの日本語設定
  3. usernameの重複を許可する
  4. emailの重複は許可しない

ビューの作成

入力フォームを作成します。

<div class="row" style="padding: 2rem;">
  <?php echo Form::open(['action' => 'home/signup', 'method' => 'post']); ?>
  <div class="form-group">
    <?php echo Form::label('ユーザー名','username'); ?>
    <?php echo Form::input('username', null, ['id' => 'username', 'class' => 'form-controll']); ?>
  </div>
  <div class="form-group">
    <?php echo Form::label('メールアドレス','email'); ?>
    <?php echo Form::input('email', null, ['id' => 'email', 'class' => 'form-controll']); ?>
  </div>
  <div class="form-group">
    <?php echo Form::label('パスワード','password'); ?>
    <?php echo Form::password('password', null, ['id' => 'password', 'class' => 'form-controll']); ?>
  </div>
  <div class="form-group">
    <?php echo Form::label('パスワード確認用','password-confirmation'); ?>
    <?php echo Form::password('password-confirmation', null, ['id' => 'password-confirmation', 'class' => 'form-controll']); ?>
  </div>
  <?php echo Form::button('新規登録', null, ['class' => 'btn btn-primary']); ?>
  <?php echo Form::close(); ?>
</div>

simpleauth.phpのコピペ、編集

packages/auth/classes/auth/login/simpleauth.php
をコピーして
packages/myauth/classes/auth/login
とフォルダを作り、ペースト
中身のcreate_user()の一部を以下のようにコメントアウトします。

public function create_user($username, $password, $email, $group = 1, Array $profile_fields = array())
	{
		$password = trim($password);
		// $email = filter_var(trim($email), FILTER_VALIDATE_EMAIL);

		// if (empty($username) or empty($password) or empty($email))
		// {
		// 	throw new \SimpleUserUpdateException('Username, password or email address is not given, or email address is invalid', 1);
		// }

		// $same_users = \DB::select_array(\Config::get('simpleauth.table_columns', array('*')))
		// 	->where('username', '=', $username)
		// 	->or_where('email', '=', $email)
		// 	->from(\Config::get('simpleauth.table_name'))
		// 	->execute(\Config::get('simpleauth.db_connection'));

		// if ($same_users->count() > 0)
		// {
		// 	if (in_array(strtolower($email), array_map('strtolower', $same_users->current())))
		// 	{
		// 		throw new \SimpleUserUpdateException('Email address already exists', 2);
		// 	}
		// 	else
		// 	{
		// 		throw new \SimpleUserUpdateException('Username already exists', 3);
		// 	}
		// }

		$user = array(
			'username'        => (string) $username,
			'password'        => $this->hash_password((string) $password),
			'email'           => $email,
			'group'           => (int) $group,
			'profile_fields'  => serialize($profile_fields),
			'last_login'      => 0,
			'login_hash'      => '',
			'created_at'      => \Date::forge()->get_timestamp(),
		);
		$result = \DB::insert(\Config::get('simpleauth.table_name'))
			->set($user)
			->execute(\Config::get('simpleauth.db_connection'));

		return ($result[1] > 0) ? $result[0] : false;
	}
    

詳しい説明などは以下の記事を参照:
https://qiita.com/kazukichi/items/2a6e242091c5f485b976#auth%E8%AA%8D%E8%A8%BC%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E7%99%BB%E9%8C%B2%E3%82%92%E8%A1%8C%E3%81%86%E9%9A%9B%E3%81%ABemail%E9%87%8D%E8%A4%87%E3%82%84username%E9%87%8D%E8%A4%87%E3%82%92%E7%84%A1%E3%81%8F%E3%81%97%E3%81%9F%E3%81%84%E5%A0%B4%E5%90%88%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E6%8B%A1%E5%BC%B5

bootstrap.phpのコピペ、編集

packages/auth/bootstrap.php

packages/myauth/
へコピペし

中身を以下のように編集します。

\Autoloader::add_core_namespace('MyAuth');

\Autoloader::add_classes(array(
	// 'Auth\\Auth'                        => __DIR__.'/classes/auth.php',
	// 'Auth\\AuthException'               => __DIR__.'/classes/auth.php',

	// 'Auth\\Auth_Driver'                 => __DIR__.'/classes/auth/driver.php',

	// 'Auth\\Auth_Opauth'                 => __DIR__.'/classes/auth/opauth.php',

	// 'Auth\\Auth_Acl_Driver'             => __DIR__.'/classes/auth/acl/driver.php',
	// 'Auth\\Auth_Acl_Simpleacl'          => __DIR__.'/classes/auth/acl/simpleacl.php',
	// 'Auth\\Auth_Acl_Ormacl'             => __DIR__.'/classes/auth/acl/ormacl.php',

	// 'Auth\\Auth_Group_Driver'           => __DIR__.'/classes/auth/group/driver.php',
	// 'Auth\\Auth_Group_Simplegroup'      => __DIR__.'/classes/auth/group/simplegroup.php',
	// 'Auth\\Auth_Group_Ormgroup'         => __DIR__.'/classes/auth/group/ormgroup.php',

	// 'Auth\\Auth_Login_Driver'           => __DIR__.'/classes/auth/login/driver.php',
	'MyAuth\\Auth_Login_Simpleauth'       => __DIR__.'/classes/auth/login/simpleauth.php',
	// 'Auth\\Auth_Login_Ormauth'          => __DIR__.'/classes/auth/login/ormauth.php',

	// 'Auth\\SimpleUserUpdateException'   => __DIR__.'/classes/auth/exceptions.php',
	// 'Auth\\SimpleUserWrongPassword'     => __DIR__.'/classes/auth/exceptions.php',
	// 'Auth\\OpauthException'             => __DIR__.'/classes/auth/exceptions.php',

	// 'Auth\\Model\\Auth_User'            => __DIR__.'/classes/model/auth/user.php',
	// 'Auth\\Model\\Auth_Userpermission'  => __DIR__.'/classes/model/auth/userpermission.php',
	// 'Auth\\Model\\Auth_Metadata'        => __DIR__.'/classes/model/auth/metadata.php',
	// 'Auth\\Model\\Auth_Group'           => __DIR__.'/classes/model/auth/group.php',
	// 'Auth\\Model\\Auth_Grouppermission' => __DIR__.'/classes/model/auth/grouppermission.php',
	// 'Auth\\Model\\Auth_Role'            => __DIR__.'/classes/model/auth/role.php',
	// 'Auth\\Model\\Auth_Rolepermission'  => __DIR__.'/classes/model/auth/rolepermission.php',
	// 'Auth\\Model\\Auth_Permission'      => __DIR__.'/classes/model/auth/permission.php',
	// 'Auth\\Model\\Auth_Provider'        => __DIR__.'/classes/model/auth/provider.php',
));

config.phpの編集

/fuel/app/config/config.phpでmyauthを読みこんでもらうように設定します。

	'always_load' => array(
		'packages' => array(
			'auth',
			'myauth', 追加
		),
	),

ここまでで、Simpleauthによるバリデーションを無効化し
自分で設定するバリデーションを使う準備が整ったので

以下では自分でバリデーションを設定していきます。

ちなみにバリデーションはどこへ書いていいのかわかりません。
Railsですとモデルのところに書くのですが、モデルの書き方をまだよく理解していないので
ひとまずコントローラーに書くことにします。

myvalidation.phpの設定

fuel/app/classes/myvalidation.phpを作成し、以下のように記述します。

<?php
class MyValidation {
    public static function _validation_unique_email($email){ 
      Validation:active()->set_message('unique_email','既に登録されています');
        $result = DB::select("email")
                ->where('email', '=', strtolower($email)) //emailを条件にDB検索
                ->from('users')->execute(); //usersテーブル内を検索
        return !($result->count() > 0); //取得件数が0より多ければfalseを返す
    }
}

コントローラ内でのバリデーション

新規アカウント登録用コントローラーで以下のように記述します。

<?php
class Controller_Home extends Controller_Template
{
  public function action_signup()
  {
    $this->template->title = '新規登録';
    $this->template->content = View::forge('home/signup'); 

    if(Input::post()){
      $val = Validation::forge();
      $val->add_callable('myvalidation');

      $val->add('username', 'ユーザー名')
          ->add_rule('required');

      $val->add('email', 'メールアドレス')
          ->add_rule('required')
          ->add_rule('valid_email')
          ->add_rule('unique_email');

      $val->add('password', 'パスワード')
          ->add_rule('required')
          ->add_rule('min_length', 8);
      
      $val->add('password-confirmation', '確認用のもの')
          ->add_rule('required')
          ->add_rule('match_field', 'password');

      if($val->run()) {
        Auth::create_user(
          $_POST['username'],
          $_POST['password'],
          $_POST['email'],
          1
        );
      } else {
        $data["subnav"] = array('signup'=> 'active' );
        $this->template->content = View::forge('home/signup', $data);
        foreach($val->error() as $key => $value) {
          $flash[] = $value->get_message()."</br>";
        }
        Session::set_flash('message', implode($flash));
      }
    }
  }
}

エラーメッセージの日本語化

/fuel/app/config/config.phpを以下のように編集します。

	'language' => 'ja',

	/**
	 *  Fallback language when file isn't available for default language.
	 */

	'language_fallback' => 'en',

	/**
	 *  PHP set_locale() setting. Use null to not set.
	 */

	'locale' => 'en_JP.utf8',

	/**
	 * -------------------------------------------------------------------------
	 *  Internal string encoding charset
	 * -------------------------------------------------------------------------
	 */

	'encoding' => 'UTF-8',

その後、app/lang/ja/validation.phpフォルダとファイルを作成し、
そこへ以下のように記述します。(適当に拾ってきたものを利用しました。)

<?php
return array(
    'required'        => ':label を入力してください。',
    'min_length'      => ':label は :param:1 文字以上で入力して下さい。',
    'max_length'      => ':label は :param:1 文字以下で入力して下さい。',
    'exact_length'    => ':label は :param:1 文字で入力して下さい。',
    'match_value'     => ':label は使用できない文字が含まれています。使用可能な文字 [:param:1] ',
    'match_pattern'   => ':label は :param:2 で入力して下さい。',
    'match_field'     => ':label は :param:1 と異なっています。',
    'valid_email'     => ':label は正しいメールアドレスではありません。',
    'valid_emails'    => ':label に不正なメールアドレスが含まれています。',
    'valid_url'       => ':label は正しいURLではありません。',
    'valid_ip'        => ':label は正しいIPアドレスではありません。',
    'numeric_min'     => ':label は :param:1 より大きい値を入力してください。',
    'numeric_max'     => ':label は :param:1 より小さい値を入力してください。',
    'numeric_between' => ':label は :param:1 以上 :param:2 以内の値を入力してください。',
    'valid_string'    => ':label は :param:1 で入力してください。',
    'required_with'   => ':label は :param:1 を1つ以上選択する必要があります。',
    'valid_date'      => ':label は 日付として正しくありません。',
);

至らない点等あればご指摘いただければ幸いです。
ありがとうございました。

参照記事:
https://qiita.com/kazukichi/items/2a6e242091c5f485b976
https://helog.jp/framework/fuelphp-auth
https://helog.jp/framework/fuelphp-validation/
https://qiita.com/Anderiens/items/3ee740065a1c725ad4b1
https://www.youtube.com/watch?v=46Hp9T1uNH0&t=325s

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?