はじめに
今回は、正規表現でパスワードのバリデーションをしてみました。
railsではformatというバリデーションヘルパーで正規表現を使用することができます。
求めるパスワードの条件として「半角6~12文字で英大文字・英小文字・数字それぞれ1文字以上含む」でないと登録できないようにしました。
実行結果はRSpecのモデルのテストで確認していきます。
参考にさせていただいた記事等
言語別:パスワード向けの正規表現
パスワード向け正規表現 /^(?=.?[a-z])(?=.?\d)[a-z\d]{8,100}$/i を解読する
前提条件
すでにユーザー作成機能作成を作成済みとします。
私はrailsチュートリアルで作成したログイン機能を使って進めました。
完成したもの先に記載するしておきます。
VALID_PASSWORD_REGEX =/\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d])\w{6,12}\z/
validates :password, presence: true,
format: { with: VALID_PASSWORD_REGEX,
message: "は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります"}
1.テストを失敗させる
失敗するテストを書く前に現状のpasswordに関するバリデーションを確認します。
現状ではパスワードが空でないこと、長さが6文字以上であることのみのバリデーションとなってます。
validates :password, presence: true, length: { minimum: 6 }
失敗するテストはこちら。
it 'パスワードに英小文字が含まれない場合無効な状態であること' do
user = User.new(password: '1'+'A' * 5, password_confirmation: '1A'+'a' * 3)
user.valid?
expect(user.errors[:password]).to include('は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります')
end
it 'パスワードに英大文字が含まれない場合無効な状態であること' do
user = User.new(password: '1'+'a' * 5, password_confirmation: '1A'+'a' * 3)
user.valid?
expect(user.errors[:password]).to include('は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります')
end
it 'パスワードに数字が含まれない場合無効な状態であること' do
user = User.new(password: 'A'+'a' * 5, password_confirmation: '1A'+'a' * 3)
user.valid?
expect(user.errors[:password]).to include('は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります')
end
it 'パスワードが5文字以下なら無効な状態であること' do
user = User.new(password: '1A'+'a' * 3, password_confirmation: '1A'+'a' * 3)
user.valid?
expect(user.errors[:password]).to include('は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります')
end
it 'パスワードが13文字以上なら無効な状態であること' do
user = User.new(password: '1A'+'a' * 11, password_confirmation: '1A'+'a' * 11)
user.valid?
expect(user.errors[:password]).to include('は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります')
end
テストをしますが失敗します。
rspec spec/models/user_spec.rb
User
パスワードに英小文字が含まれない場合無効な状態であること (FAILED - 1)
パスワードに英大文字が含まれない場合無効な状態であること (FAILED - 2)
パスワードに数字が含まれない場合無効な状態であること (FAILED - 3)
パスワードが5文字以下なら無効な状態であること (FAILED - 4)
パスワードが13文字以上なら無効な状態であること (FAILED - 5)
5 examples, 5 failures
2.コードを修正する
VALID_PASSWORD_REGEX =/\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d])\w{6,12}\z/
validates :password, presence: true,
format: { with: VALID_PASSWORD_REGEX,
message: "は半角6~12文字英大文字・小文字・数字それぞれ1文字以上含む必要があります"}
VALID_PASSWORD_REGEXにformatのwithオプションに指定する正規表現をセットします。formatではwithオプションの正規表現と属性(パスワード)がマッチするか検証します。messageには失敗したときのカスタムエラーメッセージを設定できます。(railsを日本語化していないとエラーになると思いますので日本語を使う際は注意してください。)
これでテストします。(ユーザーが有効な状態であることも確認するテストも追加)
it '名前、メール、パスワードがあれば有効な状態であること' do
user = User.new(
name: 'Aaron',
email: 'tster@example.com',
password: 'foobar12A',
password_confirmation: 'foobar12A'
)
expect(user).to be_valid
end
以下略
rspec spec/models/user_spec.rb
名前、メール、パスワードがあれば有効な状態であること
パスワードに英小文字が含まれない場合無効な状態であること
パスワードに英大文字が含まれない場合無効な状態であること
パスワードに数字が含まれない場合無効な状態であること
パスワードが5文字以下なら無効な状態であること
パスワードが13文字以上なら無効な状態であること
Finished in 0.38981 seconds (files took 3.59 seconds to load)
6 examples, 0 failures
これで期待するパスワードのバリデーションを追加することができました!