Laravel 5.8 email verify with multiple guards - laravel

I am trying to add verify email function in Laravel 5.8 i have 2 custom guards and need email verification for both guards. I am successfully verifying it for first guard but for 2nd guard verify email is not working.
Here is my verification controller.
public function __construct()
{
$this->middleware('auth:guard1');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
If i add another line of $this->middleware('auth:guard2'); in construct function both of my verifications are not working. can anyone help me here how to send verification email for multiple guards and verify their emails?
Thanks!

Related

Laravel 8 API email verification flow using Sanctum

I'm currently making an API for a mobile app but I think I'm a bit confused with how email verification and authentication is meant to work. I'm attempting to implement the following flow:
User registers in the mobile app and it sends a request to the API
Laravel creates the user and fires off an email
User receives the email and clicks on the link
Laravel verifies the user and redirects them to the mobile app via deep-link
However when the user clicks the email link a "route login not defined" error is rendered.
Which makes sense, because the user is not authenticated at the time. But am I getting this wrong?
Should I authenticate the user prior to sending the email? And will that work, given that we're using Sanctum rather than "regular" authentication?
Currently this is what I'm doing:
// web.php
Route::get('/email/verify/{id}/{hash}', [EmailVerificationController::class, 'verify'])
->middleware('signed') //note that I don't use the auth or auth:sanctum middlewares
->name('verification.verify');
// EmailVerificationController.php
public function verify(Request $request)
{
$user = User::findOrFail($request->id);
if ($user->email_verified_at) {
return '';
}
if ($user->markEmailAsVerified()) {
event(new Verified($user));
}
return redirect()->away('app://open'); // The deep link
}
Is there any security risk here? Should I at any point authenticate the user before or after they click the link?
I wanted to avoid rendering "web views" as much as possible.
I think that the best way is to implement two different paths based on the source of the user.
Regular email validation for users coming from a browser
The user will just follow the link delivered by email, you can do that with or without authentication (maybe with transparent cookie authentication). If the validation is fulfilled redirect them back to the home page.
Mobile users coming from the mobile application
I would send a PIN (with some kind of expire mechanism) via email and ask them to put it inside the APP to verify the account. This can even be protected with auth middleware using the JWT token with the verification API call.
I don't see any security issue with this last one.

Laravel's email verification redirecting to login page

I am having a problem with Laravel 5.7 Email verification.
After using Laravel's email verification it is forcing me to the login page if I'm not logged in.
Here is what we need:
We enable the code for the email verification of users. So when someone signup we want to verify the user email. We want the user to signup on the website, the user is asked to verify the email address and they can't do anything further until verified - which is ok for me.
Our trouble is, if a new user comes (Not registered) to our website, our website will force all that user to the login page as well .
A normal user who is not signed up is also getting to login page and force to verify or log in.
While we want the only user who signed up needs to verify. Which is working.
All the normal users who are not subscribed can use site easy. Where currently they are going to login page
What I've done so far
Added the following code
class User extends Authenticatable implements MustVerifyEmail
Auth::routes(['verify' => true]);
Route::get('profile', function () { })->middleware('verified');
After Verifying Emails
protected $redirectTo = '/dashboard';
It is working fine but,
What I need is that I don't want to force users to verify email because this is blocking the user from accessing the home page of my website.
The problem is you need to specify what pages will use auth middleware. To exclude your welcome view.
In your controller file.
public function __construct()
{
$this->middleware('auth')->except('welcome');
}
public function home(){
return view('welcome');
}
Im using 'welcome' view, because I believe that you do not change the code of default Laravel installation, you must be careful, since the view 'home' is the default page that laravel shows after you logged in. If you remove the authentication layer of that page, any user can access your system. You must change the code of this page or create another view.
In your web.php file
Route::get('/', 'HomeController#home');
Laravel Docs - Controller Middleware
try to add except method and check for url home
public function __construct()
{
$this->middleware(['auth', 'verified'])->except('home');
}

Laravel 5.7 verification email has wrong url when sending email through event

I'm trying to use laravel's 5.7 email verification to send an email when an account is registered. I have an event that fires that send the url when a user is registered. The event dispatch can be seen here.
protected function registered(Request $request, $user)
{
UserRegistered::dispatch($user);
}
The event fires and a listener sends an email by using the following code.
public function handle(UserRegistered $event)
{
$event->user->notify(new VerifyEmail);
}
This then does send the email verification mail to my email address so the event is working. However the issue I'm having is the verification email link that is contained in the email is incorrect.
http://localhost/email/verify/19?expires=1544182945&signature=b4337e1c7e07a7e7117a8696a30b456ab2a304cdea563ca7aea6c90bb9a2541f
Here is what is being sent by email. However the app url should not be localhost and instead by core-site.test. e.g. http://core-site.test/email/verify etc...
Does anyone know why the url is incorrect and how I can fix it?

Laravel authentication lifecycle

I'm trying to understand how an authentication request is handled by laravel in order to be able to write my own authentication method that allows me to check data from multiple tables before authenticating (basically there are some columns that I need to check to understand if a user is able to login).
I'm actually quietly confused about the relation between guards, middleware, provider and driver.
Can someone please explain me the lifecycle of a login request?
Thank you
EDIT: i'm working with laravel 5.7, standard Auth scaffolding that is available using make:auth
To make a custom authentication follow this steps
1.go to routes/web.php and make a get route to handle login view and post login route to handle login logic
Route::get('login','LoginController#show')
Route::post('login','LoginController#login')
2. Make a controller called LoginController
php artisan make:controller LoginController
4.inside LoginController make a function called login to handle login logic like this
public function login(){
$input = $this->validate(request(),['username'=>'required','password'=>'required']);
$model = CustomUsersModel::where('username',$input['username'])
->where('password',bcrypt($input['password']))->first();
if($model){
//user exist and valid login information
auth()->login($model);//login user via model
//now user loggedin
}
//handle wrong login information
}

Dingo/Api and JWT auth

I'm looking for the way to implement auth with JWT and Dingo/Api. I've added JWT package to my project. Added 'jwt' => 'Dingo\Api\Auth\Provider\JWT', into my api.php auth part.
And also added into my BaseController
public function __construct()
{
$this->middleware('api.auth');
}
How do I check if the user has permission (by role) using FormRequest? It has an authorize method, however I'm not sure how to get my user.
Since I'm using JWT the token is sent in the headers.
One way to do it is to adding the role validation to the middleware.
You can try adding this custom validation to the part where it verifies the JWT the user gave as that is the part where you can determine who is the user that owns the token.
You can use the Auth Facade to retrieve the currently authenticated user:
$user = \Auth::user()
For authorization you can use policies, see https://laravel.com/docs/5.6/authorization
Once enabled you can check for a users ability in your authorize method(s), e.g.
public function authorize() {
$user = \Auth::user();
return $user->can("do-something");
}
But there are multiple possibilities how to perform authorization checks, read the docs mentioned above for more details.

Resources