I am confused implementing forgot password functionality in fortify - laravel

With fortify in Laravel 8 I want to make
forgot-password functionality and in app/Providers/FortifyServiceProvider.php I wrote :
Fortify::requestPasswordResetLinkView(function () {
return view('auth.forgot-password');
});
Fortify::resetPasswordView(function ($request) {
return view('auth.reset-password', ['request' => $request]);
});
I filled template auth.forgot-password with design I use for enering 1 email and I recieive
email with content :
You are receiving this email because we received a password reset
request for your account.
Reset Password This password reset link will expire in 60 minutes.
If you did not request a password reset, no further action is ....
I want to replace content of this email, but I failed to find it and how can I replace it with my template?
Is value “60 minutes” configurable? How can I do it ?
Opening link in email above I see form with 3 fields Email, Password, Confirm Password. That is auth.reset-password
template and I can modify it. But I can not understand what for Password and Confirm Password inputs?
It looks like I want to modify user's password inside user's profile.
I am very confused what this functionality is for ? How can I implement forgot password functionality in fortify ?
I have config/fortify.php :
'features' => [
Features::registration(),
Features::resetPasswords(),
// Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication([
'confirmPassword' => true,
]),
],
Thanks!

I think I can answer question 2.
Go to auth.php file, change the value at 'expire' to whatever you want.
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 0,
],
],
The great issue here, is that I changed here and doesn't work. So if that works for you, please let me know.

Related

Laravel Voyager redirect to other page after login

I just started using Laravel and learning. I would like to redirect users to a custom section create through the BREAD.
In Voyager Controller, I see there is this function return Voyager::view('voyager::index');
I want to redirect to the page /admin/members
How can I achieve this? I tried to search around but can't find the solution. Hope someone can help with this. Thank you
I solved this problem by updating the user's configuration in config/voyager.php (Laravel config directory). Edit below configurations (redirect index)
'user' => [
'add_default_role_on_register' => true,
'default_role' => 'user',
'default_avatar' => 'users/default.png',
'redirect' => '/admin',
],
to
'user' => [
'add_default_role_on_register' => true,
'default_role' => 'user',
'default_avatar' => 'users/default.png',
'redirect' => '/admin/members',
],

Laravel: Set a cookie on successful login using a custom guard/attempt method

I am using a third party database for authentication. Everything is working great but now would like to set a cookie when a user has logged in.
As stated in the Laravel Docs:
The attempt method will return true if authentication was successful. Otherwise, false will be returned.
This is what I am doing in my controller:
MyLoginController.php
$user = Auth::guard('foo')->attempt(['userid' => $request->username, 'password' => $request->password], $request->remember);
dd($user);
...
return redirect()->intended(route('home'));
Everything here is great. I'm getting true or false back as expected.
What I am trying to do is if the login is successful, set a cookie on the response. I need the user object back to get a value from. Something like this:
MyLoginController.php
$user = Auth::guard('foo')->attempt(['userid' => $request->username, 'password' => $request->password], $request->remember);
if ($user) {
switch (App::environment()) {
case 'local':
$cookie = cookie('localCookieName', $user->token, 480);
break;
case 'development':
$cookie = cookie('devCookieName', $user->token, 480);
break;
case 'production':
$cookie = cookie('cookieName', $user->token, 480);
break;
default:
//
break;
}
return redirect()->intended(route('home'))->cookie($cookie);
}
return redirect()->intended(route('home'));
I am using a custom User Provider to authenticate my users - everything there is working great as well. I am getting the user, and saving any data to my local db if needed. I thought I might be able to just set the cookie in the UserProvider, but without doing ->cookie($cookie) nothing is getting set.
The value of $user->token is coming back from my 3rd party authentication. So that's why I need to be able to access that value.
Reading the docs, it looks like I need to be setting cookie(s) on the response ->cookie($cookie) or withCookies($cookies).
This leads me to believe I need to set the cookie on my controller, but I'm not sure how to get the user object back since the attempt method only returns true or false.
How can I get the user object from within the attempt method? Maybe I am making thins incredibly difficult for myself and there is an easier way to set the cookie?
Thank you for any suggestions!
EDIT
Here is my config/auth.php file:
...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'foo' => [
'driver' => 'session',
'provider' => 'foo',
],
],
...
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'foo' => [
'driver' => 'foo', // Using a 3rd party for auth.
'model' => App\MyUser::class, // User model for auth.
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
attempt does a login if the credentials are valid and correct for a User. So you can just get the user from the Request or the Auth guard, since they are logged in:
$user = $request->user();
$user = $request->auth('foo')->user();
$user = Auth::guard('foo')->user();
...
If you know that attempt passed, the User is also available via getLastAttempted on the session guard:
$user = Auth::guard('foo')->getLastAttempted();
Although you can use that I would not, as you have to check that attempt actually returned true before trusting this value. This holds the last user retrieved by credentials, which could not have been authenticated potentially, attempt returned false.
You do not have to directly be adding a cookie to the Response. In the Cookie section of the docs should be information about "queue"ing a cookie to automatically be attached to the outgoing Response:
Cookie::queue('name', 'value', $minutes);
Laravel 6.x Docs - Responses - Attaching Cookies to Responses

Need to let users login with multiple credentials same as login with other account functionality in Gmail services- Laravel

I want to let my users to login with different credentials in the same browser window, which is using the single users table. If tables were different then I will surely do that with guards, but the problem is I have to manage the user logins through single table.
Please help me how to manage multiple sessions in the same browser window, as when I login with other account in a new tab the first one goes logout.
Thanks in advance.
What I wanted to do was to maintain multiple session for a user, so he can log in with his other email-ids inside the same browser window in different tabs.
Here we go, how we can manage that and how Gmail is managing it.
At first you have to manage that, the user want to login with his other account or switch accounts. So you can show him the login page by appending any notation in url that shows he want to switch accounts.
If your original login URL is http://www.examle.com/login
then for multiple login, you can give him URL like http://www.examle.com/u/1/login (you can increase the number after u/ part as many times you want to switch accounts)
Then go to your config/sessions.php and edit your cookie part as follows
<?php
$user_type = ( ( !empty(request()) && (int)request()->segment(2) ) > 0 ? '_'. request()->segment(2) : '');
return [
//.....rest of array
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'. $user_type //This user_type generate various session keys for your multiple login according to generated URL
),
];
Then you have to change your all URL's as dynamic so that it can execute for both your normal route(without '/u/number/url' part) and with the /u/number/url part.
Define the following variable at the top of your web.php
/**
* Setting a variable to check if the user is logging in with first or multiple sessions
*/
$user_login = ( (int)request()->segment(2) > 0 ? 'u/'. request()->segment(2) : '' );
/**
* User attempting to login with other accounts
*/
Route::post($user_login. '/login', 'Auth\LoginController#login');
/**
* Get dashboard for filling the registeration forms
* Your entire app URL will now go like this, whether you can use it with user number or without it. It will go smoothly
*/
Route::get($user_login. '/dashboard', ['as' => 'dashboard', 'uses' => 'FormController#getDashboard']);
/**
* User attempting to login with other accounts
*/
Route::post($user_login. '/logout', 'Auth\LoginController#logout');
This works great. Thanks everyone for the help.
Create a new guard in admin auth with same model.
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'front' => [
'driver' => 'session',
'provider' => 'clients',
],
In the controller:
if ($this->guard()->attempt(['email' => $request->email, 'password' => $request->password, 'active' => 1])) {
dd(' i am logged in');
}
}
protected function guard()
{
return auth()->guard('front');
}

Laravel: How to use Gates with multiple Guards

I have a traditional web application that has a number of different user types, and each user type has its own Authentication guard.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admin',
],
'timekeeper' => [
'driver' => 'session',
'provider' => 'timekeeper',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
Most my users authenticate using the 'web' guard, however administrators and timekeepers each use their own guard, which is attached to an appropriate user provider.
This is fine until I try to use authentication gates. If I authenticate a user against the system's default guard (e.g. 'web'), then the gates work as expected. If I authenticate against any other guard however, then all Gate::allows(...) calls are DENIED.
Even the following ability is denied:
Gate::define('read', function ($user) {
return true;
});
Presumably this is due to line 284-286 in Illuminate\Auth\Access\Gate:
if (! $user = $this->resolveUser()) {
return false;
}
As far as I can see, my options are to:
Go back to using a single 'web' guard, with a user provider that can locate any type of user (but I'm not sure how that would work if I start using an API in parallel)
Somehow set the default guard at run time, depending on the type of the current user. (It is currently set in the config file)
Somehow inject a different user resolver in to the Gate facade (again, depending on the type of the current user)
None of these seems intuitive however. Am I missing something?
It's not the most elegant solution because it requires a lot of extra boilerplate code, but you can use Gate::forUser($user)->allows() instead of just Gate::allows() where $user comes from Auth::guard().
I had the same problem and I didn't really like this solution. After quite a lot of research I came up with this way to make your own user resolver in the Gate:
public function register()
{
$this->app->singleton(GateContract::class, function ($app) {
return new \Illuminate\Auth\Access\Gate($app, function () use($app) {
$user = call_user_func($app['auth']->userResolver());
if (is_null($user)) {
// Implement your own logic for resolving the user
}
return $user;
});
});
}
I put this in my AuthServiceProvider.

How check the user is valid or not in Laravel Passport

I try laravel passport.But i can't understand anything.
How check the user is valid or not in Laravel Passport
You can check this.
https://laravel.com/docs/5.5/passport
I will briefly explain.
After you setup Laravel-Passport to your project you should edit driver key in config/auth.php file.
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
And then make migration. Check your database. There must be tables about laravel passport.
You should post the datas below to '/user' url.
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username'=>'username',
'password'=>'password',
'scope'=>''
You must edit grant_type, client_id and client_secret keys according to values in the oauth_clients table in your database.
If you get Access-Control-Allow-Origin error you must create a middleware to allow all requests.
if (isset($request->server()['HTTP_ORIGIN'])) {
$origin = $request->server()['HTTP_ORIGIN'];
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization');
}
return $next($request);

Resources