Deviseを用いたユーザー認証を実装すると
pasword はハッシュ(不可逆暗号化)されるが
emailは不可逆暗号化はされないので、独自で実装してみた。
class User < ApplicationRecord
devise :database_authenticatable,
:registerable,
:recoverable,
:validatable,
:omniauthable,
:confirmable
before_save :encrypt_email #1
def email #3
if id.present?
decrypt(self[:email])
else
self[:email]
end
end
private
def encrypt_email #1
self.email = encrypt(email)
end
def encrypt(value_to_crypt) #2
crypt = ActiveSupport::MessageEncryptor.new(ENV["ENCRIPT_KEY"])
crypt.encrypt_and_sign(value_to_crypt)
end
def decrypt(value_to_decrypt)
crypt = ActiveSupport::MessageEncryptor.new(ENV["ENCRIPT_KEY"])
crypt.decrypt_and_verify(value_to_decrypt)
end
end
#1
before_saveで
データを保存する前に
emailを暗号化して保存する
#2
encrypt
は
ruby は2.4.1で
ActiveSupport::MessageEncryptor.new
を使ったので、
下記のエラーがよくでますが、
key must be 32 bits
上のコードの ENV["ENCRIPT_KEY"]
をぴったり32bitの文字列を適当に入れればよい
ENV["ENCRIPT_KEY"]を変えると当たり前ですが
暗号化される文字列、復号される文字列も変わります。
#3
emailを復号メソッドにしてしまうと
採番される前のARのmodelオブジェクトだと
emailが暗号されていないので、
復号前の文字列を復号してしまい
エラーが起きてしまうので
採番される前は復号せずにそのままのデータを
返すようにする。