さいしょに
下記の記事を参考にゲストログイン機能を追加しました。
簡単ログイン・ゲストログイン機能の実装方法(ポートフォリオ用)
大変参考になる、とてもわかりやすい記事でおすすめです!
それで、この記事の本題なのですが、私のポートフォリオサイト場合でセキュリティ強化のため、パスワードでバリデーション機能を追加していたので、上記記事そのままで実装するとエラーが出ましたので、その対応をまとめていきたいと思います。
エラー内容
エラーの内容は、生成されてたパスワードが、正規表現外の文字列となってしまっていたようです。
ActiveRecord::RecordInvalid (バリデーションに失敗しました: パスワードの長さは6文字以上で、大文字、小文字、数字、特殊文字がそれぞれ1つずつ含まれている必要があります。):
app/models/user.rb:41:in `guest'
app/controllers/users/sessions_controller.rb:18:in `new_guest'
パスワード生成は、SecureRandom.urlsafe_base64
で生成されていたのですが、こちらを修正する必要がありました。
def self.guest
find_or_create_by!(email: 'guest@example.com') do |user|
user.password = SecureRandom.urlsafe_base64
user.name = "ゲスト様"
user.username = "guest"
user.confirmed_at = Time.now
end
end
バリデーションは正規表現で下記のようにしていました。
validate :password_complexity
def password_complexity
return if password.blank? || password =~ /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,70}$/
errors.add :password, 'の長さは6文字以上で、大文字、小文字、数字、特殊文字がそれぞれ1つずつ含まれている必要があります。'
end
前提/実装環境
- 開発環境はDockerを使用
- Ruby:2.6.3のDockerイメージを使用
- Ruby on Rails:6.0.3
- devise (4.7.2)
修正内容
修正方法は、下記のようにパスワードを生成して対応しました。
0-9、a-z、A-Z、特殊文字の配列をsample
メソッドでランダムで4文字ずつ配列で抽出
▼ ▼ ▼
それぞれの配列をsum
メソッドで連結
▼ ▼ ▼
shuffle
メソッドで配列内の値をシャッフル
▼ ▼ ▼
join
メソッドで配列文字列を文字列に連結
def self.guest
find_or_create_by!(email: 'guest@example.com') do |user|
user.password = [
[*0..9].sample(4),
[*'a'..'z'].sample(4),
[*'A'..'Z'].sample(4),
['#', '?', '!', '@', '$', '%', '^', '&', '*', '-'].sample(4),
].sum([]).shuffle.join
user.name = "ゲスト様"
user.username = "guest"
user.confirmed_at = Time.now
end
end
さいごに
最初は、SecureRandom
メソッドで正規表現内でパスワードを生成する方法がないか調べたのですが、見つからず上記のような方法に至りました。
ちょっと無理やり感がある?ような感じがありますが、正規表現内でパスワードを生成できるようになったので良かったです。