今回は正規表現を用いて8文字以上アルファベットの大文字小文字、数字、記号を含めるようにパスワードを設定したので紹介したいと思います。やや厳しめの設定だとは思いますが、セキュリティを強くするに越したことはないので、ぜひコピペして使ってみてください。
結論
VALID_PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)(?=.*?[\W_])[!-~]{8,}+\z/
validates :password, format: { with: VALID_PASSWORD_REGEX }
これを該当モデル(Userモデル等)に設定することで、8文字以上アルファベットの大文字小文字、数字、記号を含んだパスワードのみを許容することができます。
テストコード
念のためテストコードを書き、上記の正規表現が正しいか検証してみます。
# frozen_string_literal: true
FactoryBot.define do
factory :user do
email { Faker::Internet.email }
password { 'Test1234!' }
password_confirmation { 'Test1234!' }
end
end
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe User, type: :model do
context 'パスワードのバリデーションチェック' do
it '要件通り(8文字以上でアルファベットの大文字小文字、数字、記号を含める)のパスワードを入力した場合' do
user = build(:user)
user.valid?
expect(user).to be_valid
end
it '8文字以下の場合' do
user = build(:user, password: 'Test12!')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '文字のみの場合' do
user = build(:user, password: 'Testtest')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '数字のみの場合' do
user = build(:user, password: '12345678')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '記号のみの場合' do
user = build(:user, password: '!$%&!$%&')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '小文字を入力しない場合' do
user = build(:user, password: 'TEST1234!')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '文字と数字のみの場合' do
user = build(:user, password: 'Test1234')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '文字と記号のみの場合' do
user = build(:user, password: 'Test!$%&')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
it '記号と数字のみの場合' do
user = build(:user, password: '!$%&1234')
user.valid?
expect(user.errors[:password]).to include('は有効でありません。')
end
end
end
正規表現チェッカー
念には念を入れ、正規表現チェッカーでも正しい挙動を示すか確かめてみます。
↓ ↓ ↓

まとめ
改めて8文字以上アルファベットの大文字小文字、数字、記号を含んだパスワードのみを許容する正規表現を記載すると以下のようになります。
VALID_PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)(?=.*?[\W_])[!-~]{8,}+\z/
validates :password, format: { with: VALID_PASSWORD_REGEX }
参考
今回は正規表現を用いて8文字以上アルファベットの大文字小文字、数字、記号を含めるようにパスワードを設定しました。正規表現に慣れてくるとテストを省略しがちですが、挙動を担保するためにも必ずテストコードは書いておくことをお勧めします。