【问题标题】:Laravel - How to Add Custom field in FORGOT PASSWORDLaravel - 如何在忘记密码中添加自定义字段
【发布时间】:2020-10-19 04:15:47
【问题描述】:

我正在尝试添加一个忘记密码的字段,即 STAFF ID & EMAIL。如果 STAFF ID 和 EMAIL 正确,则系统应发送重置密码链接。

似乎 laravel 默认只允许 email 忘记密码。有没有办法在发送电子邮件之前添加 STAFF IDverify 这两个字段?

vendor/laravel/framework/src/Illuminate/Foundation/Auth/SendsPasswordResetEmails.php

    <?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;

trait SendsPasswordResetEmails
{
    /**
     * Display the form to request a password reset link.
     *
     * @return \Illuminate\Http\Response
     */
    public function showLinkRequestForm()
    {
        return view('auth.passwords.email');
    }

    /**
     * Send a reset link to the given user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    public function sendResetLinkEmail(Request $request)
    {
        $this->validateEmail($request);

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        $response = $this->broker()->sendResetLink(
            $this->credentials($request)
        );

        return $response == Password::RESET_LINK_SENT
                    ? $this->sendResetLinkResponse($request, $response)
                    : $this->sendResetLinkFailedResponse($request, $response);
    }

    /**
     * Validate the email for the given request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateEmail(Request $request)
    {
        $request->validate(['email' => 'required|email']);
    
    }

    /**
     * Get the needed authentication credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(Request $request)
    {
        return $request->only('email');
        
    }

    /**
     * Get the response for a successful password reset link.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $response
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendResetLinkResponse(Request $request, $response)
    {
        return back()->with('status', trans($response));
    }

    /**
     * Get the response for a failed password reset link.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $response
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendResetLinkFailedResponse(Request $request, $response)
    {
        return back()
                ->withInput($request->only('email'))
                ->withErrors(['email' => trans($response)]);
    }

    /**
     * Get the broker to be used during password reset.
     *
     * @return \Illuminate\Contracts\Auth\PasswordBroker
     */
    public function broker()
    {
        return Password::broker();
    }
}

【问题讨论】:

    标签: laravel authentication forgot-password


    【解决方案1】:

    执行此操作的正确方法是覆盖PasswordBrokerDatabaseTokenRepository,这实际上需要做很多工作才能通过对canResetPasswordContract 稍作修改来实现。当前的实现假设重置密码完全与用户有关,并削弱了获取请求信息(例如 IP 地址)的重要性;还有高效的表索引问题。

    尽管如此,我想出了一个可能的替代品ForgotPasswordController,如果您想使用不同的表结构而不覆盖所有内容,这对于大多数用例来说应该足以更改与重置密码相关的有效负载。

    请记住

    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
    use Illuminate\Support\Facades\Password;
    use Illuminate\Support\Str;
    use Illuminate\Contracts\Auth\PasswordBroker;
    use Illuminate\Http\Request;
    use Carbon\Carbon;
    use App\Models\PasswordReset;
    use App\Models\User;
    
    class ForgotPasswordController extends Controller
    {
        /*
        |--------------------------------------------------------------------------
        | Password Reset Controller
        |--------------------------------------------------------------------------
        |
        | This controller is responsible for handling password reset emails and
        | includes a trait which assists in sending these notifications from
        | your application to your users. Feel free to explore this trait.
        |
        */    
        use SendsPasswordResetEmails;
        
        //in minutes
        protected $throttle = 60;
    
        /**
         * Send a reset link to the given user.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
         */
        public function sendResetLinkEmail(Request $request)
        {
            $this->validateEmail($request);
    
            // We will send the password reset link to this user. Once we have attempted
            // to send the link, we will examine the response then see the message we
            // need to show to the user. Finally, we'll send out a proper response.
            $user = User::where($this->credentials($request))->first();
    
            if (is_null($user)) {
                return $this->sendResetLinkFailedResponse($request, PasswordBroker::INVALID_USER);
            }
    
            $reset = PasswordReset::where(
                'email', $user->getEmailForPasswordReset()
            )->first();
    
            if ($reset && $this->tokenRecentlyCreated($reset)) {
                return $this->sendResetLinkFailedResponse($request, PasswordBroker::RESET_THROTTLED);
            }
    
            $token = $this->createToken($request, $user, $reset);
            //keep in mind that saved token is hashed version of this
            $user->sendPasswordResetNotification($token);
    
            return $this->sendResetLinkResponse($request, Password::RESET_LINK_SENT);
        }
    
        /**
         * Create a ne password reset token
         * 
         * @param  \Illuminate\Http\Request  $request
         * @param Model $user 
         * @param Model $reset
         */
        public function createToken($request, $user, $reset)
        {
            $email = $user->getEmailForPasswordReset();
    
            if ($reset) {
                $reset->delete();
            }
    
            // We will create a new, random token for the user so that we can e-mail them
            // a safe link to the password reset form. Then we will insert a record in
            // the database so that we can verify the token within the actual reset.
            $token = $this->createNewToken();
    
            PasswordReset::create([
                'user_id' => $user->id,
                'email' => $email,
                'token' => bcrypt($token),
                'created_at' => now(),
                'ip_address' => $request->ip()
            ]);
    
            return $token;
        }
    
        /**
         * Create a new token for the user.
         *
         * @return string
         */
        public function createNewToken()
        {
            return hash_hmac('sha256', Str::random(40), $this->getHashKey());
        }
    
        /**
         * Replicate hash key used by DatabaseTokenRepository
         */
        public function getHashKey()
        {
            $key = config('app.key');
            if (Str::startsWith($key, 'base64:')) {
                $key = base64_decode(substr($key, 7));
            }
            return $key;
        }
    
        /**
         * Determine if the token was recently created.
         *
         * @param  Model  $token
         * @return bool
         */
        protected function tokenRecentlyCreated($token)
        {
            if ($this->throttle <= 0) {
                return false;
            }
    
            return Carbon::parse($token->created_at)->addSeconds(
                $this->throttle
            )->isFuture();
        }
    }
    

    【讨论】:

    • 感谢您的回答。我目前的方法按预期工作,我已经使用了大约 1 年。顺便说一句,您的方法看起来既干净又实用。肯定会尝试加强它。再次感谢!
    【解决方案2】:

    终于设法在凭据中添加员工 ID :)

    <?php
    
    namespace Illuminate\Foundation\Auth;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Password;
    
    trait SendsPasswordResetEmails
    {
        /**
         * Display the form to request a password reset link.
         *
         * @return \Illuminate\Http\Response
         */
        public function showLinkRequestForm()
        {
            return view('auth.passwords.email');
        }
    
        /**
         * Send a reset link to the given user.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
         */
        public function sendResetLinkEmail(Request $request)
        {
            $this->validateEmail($request);
    
            // We will send the password reset link to this user. Once we have attempted
            // to send the link, we will examine the response then see the message we
            // need to show to the user. Finally, we'll send out a proper response.
            $response = $this->broker()->sendResetLink(
                $this->credentials($request)
            );
    
            return $response == Password::RESET_LINK_SENT
                        ? $this->sendResetLinkResponse($request, $response)
                        : $this->sendResetLinkFailedResponse($request, $response);
        }
    
        /**
         * Validate the email for the given request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return void
         */
        protected function validateEmail(Request $request)
        {
            $request->validate(['email' => 'required|email'],['StaffID' => 'required']);
        
        }
    
        /**
         * Get the needed authentication credentials from the request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return array
         */
        protected function credentials(Request $request)
        {
            return $request->only('email', 'StaffID');
            
        }
    
        /**
         * Get the response for a successful password reset link.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  string  $response
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
         */
        protected function sendResetLinkResponse(Request $request, $response)
        {
            return back()->with('status', trans($response));
        }
    
        /**
         * Get the response for a failed password reset link.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  string  $response
         * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
         */
        protected function sendResetLinkFailedResponse(Request $request, $response)
        {
            return back()
                    ->withInput($request->only('email','StaffID'))
                    ->withErrors(['email' => 'We cant find a user with that Staff ID and Email']);
        }
    
        /**
         * Get the broker to be used during password reset.
         *
         * @return \Illuminate\Contracts\Auth\PasswordBroker
         */
        public function broker()
        {
            return Password::broker();
        }
    }
    

    谢谢:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-18
      • 2017-07-23
      • 2011-12-19
      • 1970-01-01
      • 2018-03-27
      • 2019-12-26
      • 1970-01-01
      • 2015-12-21
      相关资源
      最近更新 更多