0
2

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.

Laravelでログインユーザーメールアドレスを暗号化して保存する

Last updated at Posted at 2020-09-17

Laravelのユーザー登録に関してですが、
パスワードはハッシュ化して保存されますが、メールアドレスはプレーンテキストで保存されるため、
セキュリティ強化で暗号化して保存させます。

まずはユーザーモデルのメールアドレスを取り出すときに自動で暗号化/復号化されるように設定します。

app/Models/User.php
    public function getEmailAttribute($value)
    {
        return openssl_decrypt($value, 'AES-128-ECB', '暗号化キー');
       }
    public function setEmailAttribute($value)
    {

        $this->attributes['email'] = openssl_encrypt($value, 'AES-128-ECB', '暗号化キー'));
    }

次にログイン時のメールアドレスのチェックに関してですが、そのままだと暗号化前のメールアドレスと、暗号化された文字列でログインチェックがなされるのでログインできません。
そこで、ログインチェックの前にメールアドレスを暗号化してあげます。
※追記(credentialsをオーバーライドすると回数チェックのキャッシュファイル名が変わってしまうので、loginをオーバーライドしたほうがいいです。)

app/Http/Controllers/Auth/LoginController.php

    public function login(Request $request)
    {
        $this->validateLogin($request);
        $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', \Config::get('kakecco.encryption.key'))]);
        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }
/*
    protected function credentials(Request $request)
    {
        $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', '暗号化キー')]);
        
        return $request->only($this->username(), 'password');
    }
*/

これでログインまでできるはずです。
デフォルトのままだと、ログイン失敗した後、暗号化されたメールアドレスが表示されてしまいますので適当に修正してください。

暗号化で毎回同じ文字列が作成されるためセキュリティ的にはそんなに大丈夫なわけではありませんが、平文で保存するよりはましかと思います。
また暗号化のアルゴリズムに関してですが、可逆式で毎回同じ結果で暗号化する必要があります。
Crypt::encryptStringは毎回異なる結果になるのでログイン時の処理にもうひと手間かける必要があります。

おわり。

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?