Laravel - How to Add Custom field in FORGOT PASSWORD - laravel

I am trying to add one more field to forgot password which is STAFF ID & EMAIL. If STAFF ID and EMAIL is correct then the system should send reset password link.
It seems laravel default only allow email for forgot password. Is there anyways to add STAFF ID and verify both field before send email?
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();
}
}

The proper way to do this is to override the PasswordBroker and DatabaseTokenRepository which is actually a lot of work for something that could have been achieved with a little modification to the canResetPasswordContract. The current implementation assumes resetting a password is all about the user and undermines the importance of getting the request information such as the ip address; and there's also the issue of efficient table indexing.
Nevertheless, I came up with a possible replacement of the shipped ForgotPasswordController that should be sufficient for most use cases to change the payload associated with reset password if you would like to use a different table structure without overriding everything.
Keep in mind that
<?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();
}
}

Finally manage to add staff ID in credentials :)
<?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();
}
}
Thanks :)

Related

How do I make the reset password url dynamic?

<?php
namespace Illuminate\Auth\Notifications;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
class ResetPassword extends Notification
{
/**
* The password reset token.
*
* #var string
*/
public $token;
/**
* The callback that should be used to create the reset password URL.
*
* #var \Closure|null
*/
public static $createUrlCallback;
/**
* The callback that should be used to build the mail message.
*
* #var \Closure|null
*/
public static $toMailCallback;
/**
* Create a notification instance.
*
* #param string $token
* #return void
*/
public function __construct($token)
{
$this->token = $token;
}
/**
* Get the notification's channels.
*
* #param mixed $notifiable
* #return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Build the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
if (static::$createUrlCallback) {
$url = call_user_func(static::$createUrlCallback, $notifiable, $this->token);
} else {
$url = url(route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}
return (new MailMessage)
->subject(Lang::get('Reset Password Notification'))
->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::get('Reset Password'), $url)
->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
}
/**
* Set a callback that should be used when creating the reset password button URL.
*
* #param \Closure $callback
* #return void
*/
public static function createUrlUsing($callback)
{
static::$createUrlCallback = $callback;
}
/**
* Set a callback that should be used when building the notification mail message.
*
* #param \Closure $callback
* #return void
*/
public static function toMailUsing($callback)
{
static::$toMailCallback = $callback;
}
}
Hi, I am using Laravel 7.6.2.
I keep on getting an error. I am trying to make a multiauth login system, and I am testing the password reset routes. The problem is that when I access the admin forgot password page, the email that is sent actually contains a link to the user password reset page, not the admin password reset page.
So route('password.reset' should actually be route('admin.password.reset' for the admin request. But I really have no clue how to make this URL dynamic.... Help please!!
Another option is to add this to the boot method in your AppServiceProvider:
ResetPassword::createUrlUsing(function ($notifiable, $token) {
return "http://www.my-spa.co/password/reset/{$token}";
});
I use Laravel as an API and needed this to generate a link to my single page application url.
The ResetPassword notification provided by the Laravel framework allows custom URLs out of the box. The method createUrlUsing lets you provide a function that will generate the URL in the output email.
Example in the User model class:
// Import the ResetPassword class from the framework
use Illuminate\Auth\Notifications\ResetPassword;
class User extends Authenticatable {
// ... the rest of your implementation
// The customization of the email happens here
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token) {
// The trick is first to instantiate the notification itself
$notification = new ResetPassword($token);
// Then use the createUrlUsing method
$notification->createUrlUsing(function ($token) {
return 'http://acustomurl.lol';
});
// Then you pass the notification
$this->notify($notification);
}
}
I don't know if it's completely off topic but that was what I was looking for 😅
I have done as following:
In Admin user class override sendPasswordResetNotification method:
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new AdminMailResetPasswordToken($token));
}
In AdminMailResetPasswordToken extends default Laravel ResetPassword notification class:
namespace App\Notifications\Admin\Auth;
use Illuminate\Auth\Notifications\ResetPassword;
class AdminMailResetPasswordToken extends ResetPassword
{
public static $createUrlCallback = [self::class, 'createActionUrl'];
public static function createActionUrl($notifiable, $token)
{
return url(route('admins.password.reset', [
'token' => $token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}
}
ResetPassword::createUrlUsing(function ($notifiable, $token) {
$route = Request::is('admin/password/reset')
? 'admin.password.reset'
: 'password.reset';
return url(route($route, [
'token' => $token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
});`
Here what I did in the User model
use Illuminate\Auth\Notifications\ResetPassword;
/**
* Override the mail body for reset password notification mail.
*/
public function sendPasswordResetNotification($token)
{
ResetPassword::createUrlUsing(function ($user, string $token) {
return 'https://example.com/reset-password?token='.$token;
});
$this->notify(new ResetPassword($token));
}

How to allow nova resource action in Policy

Nova 2.0
Laravel 5.8
I have one nova resource Document ( contains file url, related foreign key and title ) for which I have defined policy with create and update false and all others set to true, the PDF is generated from another resource, so I don't need to allow it to be created or edited, now everything is working fine, but with another action on this Document resource I am trying to download these files, giving me error "Sorry you are not authorized to take this action", so how to allow this action on Policy.
DocumentPolicy class
<?php
namespace App\Policies;
use App\User;
use App\Models\Document;
use Illuminate\Auth\Access\HandlesAuthorization;
class DocumentPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any documents.
*
* #param \App\User $user
* #return mixed
*/
public function viewAny(User $user)
{
return true;
}
/**
* Determine whether the user can view the document.
*
* #param \App\User $user
* #param \App\Document $document
* #return mixed
*/
public function view(User $user, Document $document)
{
return true;
}
/**
* Determine whether the user can create documents.
*
* #param \App\User $user
* #return mixed
*/
public function create(User $user)
{
return false;
}
/**
* Determine whether the user can update the document.
*
* #param \App\User $user
* #param \App\Document $document
* #return mixed
*/
public function update(User $user, Document $document)
{
return false;
}
/**
* Determine whether the user can delete the document.
*
* #param \App\User $user
* #param \App\Document $document
* #return mixed
*/
public function delete(User $user, Document $document)
{
return true;
}
/**
* Determine whether the user can restore the document.
*
* #param \App\User $user
* #param \App\Document $document
* #return mixed
*/
public function restore(User $user, Document $document)
{
return true;
}
/**
* Determine whether the user can permanently delete the document.
*
* #param \App\User $user
* #param \App\Document $document
* #return mixed
*/
public function forceDelete(User $user, Document $document)
{
return true;
}
public function download(User $user, Document $document)
{
return true;
}
}
The reason why you are getting the error is because your update method returns false in your policy.
By default, if the update is false, Nova will not allow the action. To test this, you can try to set it to true and test it again.
To fix this, you'd have to change the way you are registering the action to add a custom callback to handle if the user can run the action or not like this:
public function actions(Request $request)
{
return [
(new DownloadDocument)->canRun(function ($request, $document) {
return $request->user()->can('download', $document);
}),
];
}
With this, it will check for the download method in your document policy instead of the update method for the action.
For more information: https://nova.laravel.com/docs/2.0/actions/registering-actions.html#authorizing-actions-per-resource

How to change Password column Field for Laravel 5.2 password reset

I have a project being developed in laravel 5.2, I currently am having troubles with the password reset to work. At the moment I have it looking for the correct email field and to let the user request a password reset email with link to reset it, then after the user clicks the link in the email the user will be presented with the form to change their password. When they submit their new password they are presented with this error:
QueryException in Connection.php line 729:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'password_confirmation' in 'where clause' (SQL: select * from all_user where user_email = ...#hotmail.com and password_confirmation = 123456 limit 1)
I dont know why its checking in the sql statement for a field called password_confirmation. This error is getting caused by trying to get the user so it can perform the password reset. This is in the PasswordBroker.php file and the getUser function. More specifically the line $user = $this->users->retrieveByCredentials($credentials);
My current code I modified so far:
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;
}
}

how to fix error for laravel 5.2

i have a work on create custom driver in laravel 5.2.My code is below here.
my auth.php has
'providers' => [
'users' => [
'driver' => 'bootsgrid',
],
And my app.php have
App\Bootsgrid\Authentication\AuthServiceProvider::class,
my custom driver controller below there
<?php
namespace App\Bootsgrid\Authentication;
use Auth;
use App\Bootsgrid\Authentication\UserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* #return void
*/
public function boot()
{
Auth::provider('bootsgrid', function($app, array $config) {
return new UserProvider();
});
}
/**
* Register bindings in the container.
*
* #return void
*/
public function register()
{
//
}
}
And my provider file there
<?php
namespace App\Bootsgrid\Authentication;
use App\Bootsgrid\Authentication\User;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
class UserProvider implements IlluminateUserProvider
{
/**
* #param mixed $identifier
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
// Get and return a user by their unique identifier
}
/**
* #param mixed $identifier
* #param string $token
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// Get and return a user by their unique identifier and "remember me" token
}
/**
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param string $token
* #return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// Save the given "remember me" token for the given user
}
/**
* Retrieve a user by the given credentials.
*
* #param array $credentials
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// Get and return a user by looking up the given credentials
}
/**
* Validate a user against the given credentials.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param array $credentials
* #return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
// Check that given credentials belong to the given user
}
}
This is all my code but i got a error below this
Declaration of App\Bootsgrid\Authentication\UserProvider::updateRememberToken() must be compatible with Illuminate\Contracts\Auth\UserProvider::updateRememberToken(Illuminate\Contracts\Auth\Authenticatable $user, $token)
i dont know How to fix it.please help me.
Put this underneath your namespace declaration: use Illuminate\Contracts\Auth\Authenticatable;.

Laravel 5 authentication weird behaviour

Before explaining the problem. Let me explain, things i have tried out.I ran the command
php artisan make:auth
it created files like HomeController, a directory auth which had register & login pages. in my application i have a directory Pages. i opened up AuthenticatesUsers trait and changed
return view('auth.login'); to my view return view('Pages.login');
After that: i changed view of showRegistrationForm methods view return view('auth.register'); to return view('Pages.register'); from RegistersUsers.php
Here is UserController
lass UserController extends Controller {
//constructor
public function __construct() {
}
//Admin: return view
public function showCommunity() {
$Community = Community::latest()->get();
$Ideas = Idea::latest()->get();
return view('privatePages.communities', compact(array('Community', 'Ideas')));
}
Routes that were generated by php artisan make:auth
Route::auth();
//Auth Controller
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Now coming back to the problem. yesterday morning. When i opened up localhost/auth/register. Registration process was working fine and data was storing in DB. But there was an issue with login view. Neither it was throwing an error on wrong credentials nor logged the user in on correct credentials. Later in the evening. Login view was working and throwing an error even upon entering correct credentials it said Credentials does not match record. But registration process was not working and data was not storing in DB. It really confusing.
Here is AutheticatesUsers File
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;
//use App\Http\Requests\UserRequest;
trait AuthenticatesUsers
{
use RedirectsUsers;
/**
* Show the application login form.
*
* #return \Illuminate\Http\Response
*/
public function getLogin()
{
return $this->showLoginForm();
}
/**
* Show the application login form.
*
* #return \Illuminate\Http\Response
*/
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('Pages.login');
}
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
return $this->login($request);
}
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
// 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.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// 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.
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
/**
* Validate the user login request.
*
* #param \Illuminate\Http\Request $request
* #return void
*/
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required',
]);
}
/**
* Send the response after the user was authenticated.
*
* #param \Illuminate\Http\Request $request
* #param bool $throttles
* #return \Illuminate\Http\Response
*/
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}
/**
* Get the failed login response instance.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
protected function sendFailedLoginResponse(Request $request)
{
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
/**
* Get the failed login message.
*
* #return string
*/
protected function getFailedLoginMessage()
{
return Lang::has('auth.failed')
? Lang::get('auth.failed')
: 'These credentials do not match our records.';
}
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function getCredentials(Request $request)
{
return $request->only($this->loginUsername(), 'password');
}
/**
* Log the user out of the application.
*
* #return \Illuminate\Http\Response
*/
public function getLogout()
{
return $this->logout();
}
/**
* Log the user out of the application.
*
* #return \Illuminate\Http\Response
*/
public function logout()
{
Auth::guard($this->getGuard())->logout();
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
/**
* Get the guest middleware for the application.
*/
public function guestMiddleware()
{
$guard = $this->getGuard();
return $guard ? 'guest:'.$guard : 'guest';
}
/**
* Get the login username to be used by the controller.
*
* #return string
*/
public function loginUsername()
{
return property_exists($this, 'username') ? $this->username : 'email';
}
/**
* Determine if the class is using the ThrottlesLogins trait.
*
* #return bool
*/
protected function isUsingThrottlesLoginsTrait()
{
return in_array(
ThrottlesLogins::class, class_uses_recursive(static::class)
);
}
/**
* Get the guard to be used during authentication.
*
* #return string|null
*/
protected function getGuard()
{
return property_exists($this, 'guard') ? $this->guard : null;
}
}
One more thing for registration process. I am not using laravel's Request rather my own created 'UserRequest`. If any other information is needed. i would provide that. Any help would be appreciated.

Resources