我在laravel 5.2中开发了一个项目,我目前在密码重置工作时遇到了麻烦。目前我正在寻找正确的电子邮件字段,并让用户请求密码重置电子邮件,并附带重置链接,然后在用户点击电子邮件中的链接后,将向用户显示更改密码的表单。当他们提交新密码时,会出现此错误:
Connection.php第729行中的QueryException:
SQLSTATE [42S22]:未找到列:1054未知列' password_confirmation'在' where子句' (SQL:从all_user
中选择* user_email
= ... @ hotmail.com和password_confirmation
= 123456限制1)
我不知道为什么在sql语句中检查一个名为password_confirmation的字段。尝试获取用户以便它可以执行密码重置,从而导致此错误。这是在PasswordBroker.php文件和getUser函数中。更具体地说,行$ user = $ this-> users-> retrieveByCredentials($ credentials);
我目前修改的代码:
ResetsPasswords.php
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Password;
trait ResetsPasswords
{
use RedirectsUsers;
/**
* Get the name of the guest middleware.
*
* @return string
*/
protected function guestMiddleware()
{
$guard = $this->getGuard();
return $guard ? 'guest:'.$guard : 'guest';
}
/**
* Display the form to request a password reset link.
*
* @return \Illuminate\Http\Response
*/
public function getEmail()
{
return $this->showLinkRequestForm();
}
/**
* Display the form to request a password reset link.
*
* @return \Illuminate\Http\Response
*/
public function showLinkRequestForm()
{
if (property_exists($this, 'linkRequestView')) {
return view($this->linkRequestView);
}
if (view()->exists('auth.passwords.email')) {
return view('auth.passwords.email');
}
return view('auth.password');
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postEmail(Request $request)
{
return $this->sendResetLinkEmail($request);
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function sendResetLinkEmail(Request $request)
{
$request['user_email'] = $request['email'];
$this->validateSendResetLinkEmail($request);
$broker = $this->getBroker();
$response = Password::broker($broker)->sendResetLink(
$this->getSendResetLinkEmailCredentials($request),
$this->resetEmailBuilder()
);
return dd($request);
switch ($response) {
case Password::RESET_LINK_SENT:
return $this->getSendResetLinkEmailSuccessResponse($response);
case Password::INVALID_USER:
default:
return $this->getSendResetLinkEmailFailureResponse($response);
}
}
/**
* Validate the request of sending reset link.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function validateSendResetLinkEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
}
/**
* Get the needed credentials for sending the reset link.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function getSendResetLinkEmailCredentials(Request $request)
{
return $request->only('user_email');
}
/**
* Get the Closure which is used to build the password reset email message.
*
* @return \Closure
*/
protected function resetEmailBuilder()
{
return function (Message $message) {
$message->subject($this->getEmailSubject());
};
}
/**
* Get the e-mail subject line to be used for the reset link email.
*
* @return string
*/
protected function getEmailSubject()
{
return property_exists($this, 'subject') ? $this->subject : 'Your Password Reset Link';
}
/**
* Get the response for after the reset link has been successfully sent.
*
* @param string $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getSendResetLinkEmailSuccessResponse($response)
{
return redirect()->back()->with('status', trans($response));
}
/**
* Get the response for after the reset link could not be sent.
*
* @param string $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getSendResetLinkEmailFailureResponse($response)
{
return redirect()->back()->withErrors(['email' => trans($response)]);
}
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* @param \Illuminate\Http\Request $request
* @param string|null $token
* @return \Illuminate\Http\Response
*/
public function getReset(Request $request, $token = null)
{
return $this->showResetForm($request, $token);
}
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* @param \Illuminate\Http\Request $request
* @param string|null $token
* @return \Illuminate\Http\Response
*/
public function showResetForm(Request $request, $token = null)
{
if (is_null($token)) {
return $this->getEmail();
}
$email = $request->input('email');
if (property_exists($this, 'resetView')) {
return view($this->resetView)->with(compact('token', 'email'));
}
if (view()->exists('auth.passwords.reset')) {
return view('auth.passwords.reset')->with(compact('token', 'email'));
}
return view('auth.reset')->with(compact('token', 'email'));
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postReset(Request $request)
{
return $this->reset($request);
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function reset(Request $request)
{
$request['user_email'] = $request['email'];
$request['user_password'] = $request['password'];
$this->validate(
$request,
$this->getResetValidationRules(),
$this->getResetValidationMessages(),
$this->getResetValidationCustomAttributes()
);
$credentials = $this->getResetCredentials($request);
$broker = $this->getBroker();
//return dd($credentials);
$response = Password::broker($broker)->reset($credentials, function ($user, $password) {
return dd($password);
$this->resetPassword($user, $password);
});
//return dd($request);
switch ($response) {
case Password::PASSWORD_RESET:
return $this->getResetSuccessResponse($response);
default:
return $this->getResetFailureResponse($request, $response);
}
}
/**
* Get the password reset validation rules.
*
* @return array
*/
protected function getResetValidationRules()
{
return [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:6',
];
}
/**
* Get the password reset validation messages.
*
* @return array
*/
protected function getResetValidationMessages()
{
return [];
}
/**
* Get the password reset validation custom attributes.
*
* @return array
*/
protected function getResetValidationCustomAttributes()
{
return [];
}
/**
* Get the password reset credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function getResetCredentials(Request $request)
{
return $request->only(
'user_email', 'user_password', 'password_confirmation', 'token'
);
}
/**
* Reset the given user's password.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $password
* @return void
*/
protected function resetPassword($user, $password)
{
$user->forceFill([
'user_password' => bcrypt($password),
'remember_token' => Str::random(60),
])->save();
Auth::guard($this->getGuard())->login($user);
}
/**
* Get the response for after a successful password reset.
*
* @param string $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getResetSuccessResponse($response)
{
return redirect($this->redirectPath())->with('status', trans($response));
}
/**
* Get the response for after a failing password reset.
*
* @param Request $request
* @param string $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getResetFailureResponse(Request $request, $response)
{
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['email' => trans($response)]);
}
/**
* Get the broker to be used during password reset.
*
* @return string|null
*/
public function getBroker()
{
return property_exists($this, 'broker') ? $this->broker : null;
}
/**
* Get the guard to be used during password reset.
*
* @return string|null
*/
protected function getGuard()
{
return property_exists($this, 'guard') ? $this->guard : null;
}
}
CanResetPassword.php
<?php
namespace Illuminate\Auth\Passwords;
trait CanResetPassword
{
/**
* Get the e-mail address where password reset links are sent.
*
* @return string
*/
public function getEmailForPasswordReset()
{
return $this->user_email;
}
}
PasswordBroker.php
<?php
namespace Illuminate\Auth\Passwords;
use Closure;
use Illuminate\Support\Arr;
use UnexpectedValueException;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Auth\PasswordBroker as PasswordBrokerContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class PasswordBroker implements PasswordBrokerContract
{
/**
* The password token repository.
*
* @var \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
protected $tokens;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $users;
/**
* The mailer instance.
*
* @var \Illuminate\Contracts\Mail\Mailer
*/
protected $mailer;
/**
* The view of the password reset link e-mail.
*
* @var string
*/
protected $emailView;
/**
* The custom password validator callback.
*
* @var \Closure
*/
protected $passwordValidator;
/**
* Create a new password broker instance.
*
* @param \Illuminate\Auth\Passwords\TokenRepositoryInterface $tokens
* @param \Illuminate\Contracts\Auth\UserProvider $users
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param string $emailView
* @return void
*/
public function __construct(TokenRepositoryInterface $tokens,
UserProvider $users,
MailerContract $mailer,
$emailView)
{
$this->users = $users;
$this->mailer = $mailer;
$this->tokens = $tokens;
$this->emailView = $emailView;
}
/**
* Send a password reset link to a user.
*
* @param array $credentials
* @param \Closure|null $callback
* @return string
*/
public function sendResetLink(array $credentials, Closure $callback = null)
{
// First we will check to see if we found a user at the given credentials and
// if we did not we will redirect back to this current URI with a piece of
// "flash" data in the session to indicate to the developers the errors.
$user = $this->getUser($credentials);
if (is_null($user)) {
return static::INVALID_USER;
}
// Once we have the reset token, we are ready to send the message out to this
// user with a link to reset their password. We will then redirect back to
// the current URI having nothing set in the session to indicate errors.
//return dd($credentials);
$token = $this->tokens->create($user);
$this->emailResetLink($user, $token, $callback);
return static::RESET_LINK_SENT;
}
/**
* Send the password reset link via e-mail.
*
* @param \Illuminate\Contracts\Auth\CanResetPassword $user
* @param string $token
* @param \Closure|null $callback
* @return int
*/
public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
{
// We will use the reminder view that was given to the broker to display the
// password reminder e-mail. We'll pass a "token" variable into the views
// so that it may be displayed for an user to click for password reset.
$view = $this->emailView;
return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
$m->to($user->getEmailForPasswordReset());
if (! is_null($callback)) {
call_user_func($callback, $m, $user, $token);
}
});
}
/**
* Reset the password for the given token.
*
* @param array $credentials
* @param \Closure $callback
* @return mixed
*/
public function reset(array $credentials, Closure $callback)
{
// If the responses from the validate method is not a user instance, we will
// assume that it is a redirect and simply return it from this method and
// the user is properly redirected having an error message on the post.
//return dd($credentials);
$user = $this->validateReset($credentials);
if (! $user instanceof CanResetPasswordContract) {
return $user;
}
$pass = $credentials['user_password'];
// Once we have called this callback, we will remove this token row from the
// table and return the response from this callback so the user gets sent
// to the destination given by the developers from the callback return.
call_user_func($callback, $user, $pass);
$this->tokens->delete($credentials['token']);
return static::PASSWORD_RESET;
}
/**
* Validate a password reset for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*/
protected function validateReset(array $credentials)
{
if (is_null($user = $this->getUser($credentials))) {
return static::INVALID_USER;
}
if (! $this->validateNewPassword($credentials)) {
return static::INVALID_PASSWORD;
}
if (! $this->tokens->exists($user, $credentials['token'])) {
return static::INVALID_TOKEN;
}
return $user;
}
/**
* Set a custom password validator.
*
* @param \Closure $callback
* @return void
*/
public function validator(Closure $callback)
{
$this->passwordValidator = $callback;
}
/**
* Determine if the passwords match for the request.
*
* @param array $credentials
* @return bool
*/
public function validateNewPassword(array $credentials)
{
list($password, $confirm) = [
$credentials['user_password'],
$credentials['password_confirmation'],
];
if (isset($this->passwordValidator)) {
return call_user_func(
$this->passwordValidator, $credentials) && $password === $confirm;
}
return $this->validatePasswordWithDefaults($credentials);
}
/**
* Determine if the passwords are valid for the request.
*
* @param array $credentials
* @return bool
*/
protected function validatePasswordWithDefaults(array $credentials)
{
list($password, $confirm) = [
$credentials['user_password'],
$credentials['password_confirmation'],
];
return $password === $confirm && mb_strlen($password) >= 6;
}
/**
* Get the user for the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\CanResetPassword
*
* @throws \UnexpectedValueException
*/
public function getUser(array $credentials)
{
$credentials = Arr::except($credentials, ['token']);
//$credentials = Arr::except($credentials, ['password_confirmation']);
//return dd($credentials);
$user = $this->users->retrieveByCredentials($credentials);
//return dd($credentials);
//$credentials = $credentials['password_confirmation'];
if ($user && ! $user instanceof CanResetPasswordContract) {
throw new UnexpectedValueException('User must implement CanResetPassword interface.');
}
return $user;
}
/**
* Create a new password reset token for the given user.
*
* @param CanResetPasswordContract $user
* @return string
*/
public function createToken(CanResetPasswordContract $user)
{
return $this->tokens->create($user);
}
/**
* Delete the given password reset token.
*
* @param string $token
* @return void
*/
public function deleteToken($token)
{
$this->tokens->delete($token);
}
/**
* Validate the given password reset token.
*
* @param CanResetPasswordContract $user
* @param string $token
* @return bool
*/
public function tokenExists(CanResetPasswordContract $user, $token)
{
return $this->tokens->exists($user, $token);
}
/**
* Get the password reset token repository implementation.
*
* @return \Illuminate\Auth\Passwords\TokenRepositoryInterface
*/
public function getRepository()
{
return $this->tokens;
}
}