突然得到"这些凭据与我们的记录不符。"在幼虫5.2 - 想法?

时间:2017-05-17 15:55:17

标签: authentication laravel-5

我的应用程序工作正常,直到今天。我可以登录,注销,重新登录。事情似乎奏效了。然后我决定测试重置密码功能。我不是网站开发人员。事实上,我正在做一些彻底的测试。我知道 - 我应该和开发人员一起测试。

无论如何,这就是现在发生的事情:

  1. 转到登录页面,然后单击忘记密码链接
  2. 输入帐户电子邮件
  3. 点击电子邮件中的重置链接
  4. 指定新密码
  5. 使用新密码自动登录。
  6. 注销
  7. 点击登录并输入凭据
  8. 收到恼人的错误"这些凭据与我们的记录不符。"
  9. /config/auth.php文件包含:

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */
    
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */
    
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],
    
    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */
    
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
    
        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | Here you may set the options for resetting passwords including the view
    | that is your password reset e-mail. You may also set the name of the
    | table that maintains all of the reset tokens for your application.
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */
    
    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],
    ];
    

    问题可能与成功登录后发生的事情有关。 AuthController是

    <?php
    namespace App\Http\Controllers\Auth;
    
    use App\User;
    use Validator;
    use App\Http\Controllers\Controller;
    use Illuminate\Foundation\Auth\ThrottlesLogins;
    use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
    use Illuminate\Http\Request;
    use Illuminate\Contracts\Mail\Mailer;
    use Auth;
    use Exception;
    use Event;
    use App\Events\UserVerifiedEvent;
    
    class AuthController extends Controller
    {
        /*
        |--------------------------------------------------------------------------
        | Registration & Login Controller
        |--------------------------------------------------------------------------
        |
        | This controller handles the registration of new users, as well as the
        | authentication of existing users. By default, this controller uses
        | a simple trait to add these behaviors. Why don't you explore it?
        |
        */
    
        use AuthenticatesAndRegistersUsers, ThrottlesLogins;
    
        /**
         * Where to redirect users after login / registration.
         *
         * @var string
         */
        protected $redirectTo = '/';
    
        /**
         * Create a new authentication controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('guest', ['except' => 'logout']);
        }
    
        /**
         * Get a validator for an incoming registration request.
         *
         * @param  array  $data
         * @return \Illuminate\Contracts\Validation\Validator
         */
        protected function validator(array $data)
        {
            return Validator::make($data, [
                'name' => 'required|max:255',
                'email' => 'required|email|max:255|unique:users',
                'password' => 'required|confirmed|min:6',
                'subscribe' => 'min:1',
            ]);
        }
    
        /**
         * Create a new user instance after a valid registration.
         *
         * @param  array  $data
         * @return User
         */
        protected function create(array $data)
        {
            $data['subscribe'] = ($data['subscribe'] == 1) ? 1 : 0;
            return User::create([
                'name' => $data['name'],
                'email' => $data['email'],
                'subscribe' => $data['subscribe'],
                'password' => bcrypt($data['password']),
            ]);
        }
    
        /**
         * Overrides AuthenticatesUsers trait method.
         * Custom registration request handling for the application.
         */
        public function register(Request $request, Mailer $mailer)
        {
            $validator = $this->validator($request->all());
    
            if ($validator->fails()) {
                $this->throwValidationException(
                    $request, $validator
                );
            }
    
            $user = $this->create($request->all());
    
            $mailer->send('auth/emails/verification', ['token' => $user->email_token], function ($message) use ($user) {
                $message->from('from', 'site')
                    ->to($user->email)
                    ->subject('Email Verification');
            });
    
            return view('auth/register')->withSuccess(true);
        }
    
        public function verifyEmail($token)
        {
            if ($token == null || $token == '') throw new Exception('Token must not be empty.');
    
            $user = \App\User::where('email_token', $token)->first();
            if ($user != null && !$user->verified)
            {
                $user->createProfile();
                $user->verifyEmail();
    
                Event::fire(new UserVerifiedEvent($user));
    
                //Auth::guard($this->getGuard())->login($user); // This could pose a security risk!
            }
            return redirect('/profile/welcome');
        }
    
        /**
         * Overrides AuthenticatesUsers trait method.
         * Custom credentials extraction method.
         */
        protected function getCredentials(Request $request)
        {
            return [
                'email' => $request['email'],
                'password' => $request['password'],
                'subscribe' => $request['subscribe'],
                'verified' => true
            ];
        }
    }
    

    这里唯一值得一提的是我添加了&#39;订阅&#39;注册字段的字段,这是我对上面文件的唯一编辑。我无法看到这会对事情产生什么影响,所以我认为这个问题与登录操作有关,也可能是令牌或者没有被重置的事情。

    当我使用PHPStorm在调试模式下运行所有​​内容时,我可以看到正确检索了电子邮件和密码。只是无法弄清楚核心Auth例程在哪里决定登录无效。

    另外值得注意的是,当错误发生时,电子邮件字段标记为红色。但这可能只是默认行为,无论哪个字段导致错误。

    这是密码控制器:

    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use Hash;
    use Auth;
    use Illuminate\Http\Request;
    use App\Http\Controllers\Controller;
    use Illuminate\Foundation\Auth\ResetsPasswords;
    use Illuminate\Support\MessageBag;
    
    class PasswordController extends Controller
    {
        /*
        |--------------------------------------------------------------------------
        | Password Reset Controller
        |--------------------------------------------------------------------------
        |
        | This controller is responsible for handling password reset requests
        | and uses a simple trait to include this behavior. You're free to
        | explore this trait and override any methods you wish to tweak.
        |
        */
    
        use ResetsPasswords;
    
        /**
         * Create a new password controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('guest', [
                'except' => ['showChangePasswordForm', 'changePassword']
            ]);
        }
    
        public function showChangePasswordForm()
        {
            return view('auth/passwords/change');
        }
    
        public function changePassword(Request $request)
        {
            $this->validate($request, [
                'old_password' => 'required',
                'password' => 'required|confirmed',
                'password_confirmation' => 'required',
            ]);
    
            $user = Auth::user();
            if (Hash::check($request['old_password'], $user->password))
            {
                $user->password = Hash::make($request['password']);
                $user->save();
                return view('auth/passwords/change')->withSuccess(true);
            }
            else
            {
                $errors = new MessageBag();
                $errors->add('old_password', 'Wrong password.');
                return redirect('/password/change')->withErrors($errors);
            }
        }
    }
    

    以下是一些可能在这里发挥作用的中间件功能:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Support\Facades\Auth;
    
    class Authenticate
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @param  string|null  $guard
         * @return mixed
         */
        public function handle($request, Closure $next, $guard = null)
        {
            if (Auth::guard($guard)->guest()) {
                if ($request->ajax() || $request->wantsJson()) {
                    return response('Unauthorized.', 401);
                } else {
                    return redirect()->guest('login');
                }
            }
    
            return $next($request);
        }
    }
    
    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Support\Facades\Auth;
    
    class RedirectIfAuthenticated
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @param  string|null  $guard
         * @return mixed
         */
        public function handle($request, Closure $next, $guard = null)
        {
            if (Auth::guard($guard)->check()) {
                return redirect()->intended('/'); // Uses Session
            }
    
            return $next($request);
        }
    }
    

    这是一个参与登录的监听器:

    <?php
    
    namespace App\Listeners;
    
    use Illuminate\Auth\Events\Login;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class SuccessfulLoginListener
    {
        /**
         * Create the event listener.
         *
         * @return void
         */
        public function __construct()
        {
            //
        }
    
        /**
         * Handle the event.
         *
         * @param  Login  $event
         * @return void
         */
        public function handle(Login $event)
        {
            $user = $event->user;
            $user->last_login_at = \Carbon\Carbon::now();
    
            $user->save();
        }
    }
    

    这些是我可以找到的应用程序中的所有代码片段,它们似乎在登录和退出中起作用(前者比后者更多!)

    我每次都重复这个问题。我每次都输入相同的登录凭据。所以登录/注销过程在某种程度上导致一些奇怪的状态,我很难调试。我还检查了数据库,没有看到任何会导致检索到的数据与凭证不匹配的奇怪数据。

    如果有人在上面看到一些明显错误,请告诉我。

    谢谢!

    PS - 值得一提的另一点 - 这个问题发生在同一时间我为应用创建了第二个用户,这是通过应用程序的注册页面完成的。我使用与其他用户相同的密码。我打开了多个浏览器,有多个选项卡,还有几个登录会话实例。也许这也是谜语的关键?

1 个答案:

答案 0 :(得分:0)

弄清楚问题 - 在AuthController中,我已将'subscribe'字段添加到getCredentials函数中。绝对造成了问题!一切都很好。