Google2FALaravel Authenticator always return True in Laravel 6 - laravel

There is a problem using the Google-Authenticator Module "PragmaRX\Google2FALaravel" in my Laravel6 project.
I installed it following the manual on the github page. Setting up 2FA-Users via QRcode works like a charm, but the authentication middleware always returns "True" for authenticated, regardless if the user has passed the 2fa challenge or not.
public function handle($request, Closure $next)
{
$authenticator = app(Google2FAAuthenticator::class)->boot($request);
if ($authenticator->isAuthenticated()) { **//always returns true**
return $next($request);
}
return $authenticator->makeRequestOneTimePasswordResponse();
}
I assume it has something to do with the "CARTALYST/Sentinel" package i am using (instead of the built-in laravel "Auth" Manager), someone experienced similar behaviour and knows how to fix this?

Related

Auth facade doesn't work without Sanctum api as middleware in Laravel 8

I'm creating an api through which anybody can view a page, however only admin can see all posts, while users are restricted to approved only. This is implemented via is_verified boolean variable where admin is given value of 1 and user the value of 0. I want to create a function like this
public function show(){
if(Auth::check()){
$showAllDetails = Events::all();
echo $showAllDetails;
}else {
$showUserDetails = Events:all()->where('is_verified',1);
echo $showUserDetails;
}
}
However Auth:check only works if I have sanctum api in my route
Route::middleware('auth:sanctum')->group(function () {
Route::get('view', [ViewController::class, 'show']);
});
If I run this code on Hoppscotch, it only shows if the admin is logged in (User don't require login). So a user can't see any post. If I remove the auth:sanctum middleware, only the else part of the code runs and no auth check or any stuff can run .
I need a way to incorporate both in a single function so that I can create a single route instead of creating two routes for different persons. Any way of doing such things?
public function show(){
if(Auth::check()){
$showAllDetails = Events::all();
echo $showAllDetails;
}else {
$showUserDetails = Events::where('is_verified',1)->get();
echo $showUserDetails;
}
}
I guess your else part is incorrect query, change your else part like above

Laravel middleware to check user has access - if not do not proceed with controller method?

Googled and tried for hours now, i need help. Laravel 9.x here.
I use ajax calls which are handled by controllers.
Before the controller handles them, i need to check if the user has indeed access to the administration the user is requesting data for.
The problem is the return false in the middleware class. How can i return a response to the browser without executing any method inside the requested controller class?
The middleware i'm using:
namespace App\Http\Middleware;
use Closure;
class CheckUserAccessToAdministration {
public function handle($request, Closure $next)
{
// Check if the user has access rights to the requested administration
$allowedAdministrations = $request->session()->get('allowed_administrations');
$administration = $request->adm;
if(!in_array($administration, $allowedAdministrations)){
// the idea is that i stop execution of the call, not execute controller method
and just return a message to the browser. i use return false atm, but that isn't right,
i think.
return false;
}
return $next($request);
} }

Is it possible to force logout using user id in Laravel?

I'm wondering if there is any simple way to force logout different users by their id? For example I need to block currently lodged in user so I want to log out him after I set his status to block.
P.S.
I cant use middleware for this to check on each request.
I do this inside the Authenticate middleware
if (!Auth::user()->isActive()) {
Auth::logout();
return Redirect::home();
}
The user is already loaded there, no additional database query is needed here.
I don't think that's a performance issue, you just do a little if statement and you do it only if the user needs to be authenticated.
It's super easy if you are using database session driver:
DB::table('sessions')->where('user_id', $userId)->delete();
#PerterPan666 thanks, ya i ended up creating a middleware and adding it to the web group.
public function handle($request, Closure $next)
{
if (Auth::check())
{
if (Auth::User()->is_active != 'Y')
{
Auth::logout();
return redirect()->to('/')->with('warning', 'Your session has expired because your account is deactivated.');
}
}
return $next($request);
}
For anyone using later Laravel 5.6+, there's a method available for this built in. Doesn't mention where to call logoutOtherDevices, but LoginController#authenticated looks to work well as you can pass through their password, as required by the method
https://laravel.com/docs/5.8/authentication#invalidating-sessions-on-other-devices
public function authenticated(Request $request, $throttles)
{
\Illuminate\Support\Facades\Auth::logoutOtherDevices($request->get('password'));

Set Locale when using Auth::loginUsingId for phpunit

I have several languages in my Laravel 5.2 app. Each locale is stored in DB in th User Model. So, each time a user log, the locale must update.
Thing is in my Test, I use a lot Auth::loginUsingId, because I need to test function with differents user profiles.
So, I don't want to append to each of those calls with a App::setLocale(Auth::user->locale), nor extract it to a function.
Any Idea how should I do it???
What I did to address this problem is creating a middleware with
public function handle($request, Closure $next)
{
if ($user = Auth::user()) {
App::setLocale($user->locale);
}
return $next($request);
}
By handling all routes through this middleware, you can have the locale set automatically at each request.

Laravel middleware one time authorization for route groups

I am designing some part of system in Laravel 5. It is expected to behavior as described below.
User gets unique url. It could be provided in email, but that will not matter.
He clicks it, and gets logged in with some temporary token (for a session lifetime), that gives him possibility to access all the urls in allowed route group, ex. account/*, but if he wants to reach other restricted urls, then he is asked to authorize with his username/password.
If he is already authorized, token login makes no effect for him.
My question is about possibility to do something like that in Laravel out of box. I know there are some middleware services, but I'm not sure if default Guard behavior will not need to be changed to work as I expect.
I used to work with Symfony before, and there it is solved by firewalls by default, so maybe also in Laravel there is prebuilt solution?
you can absolutely doing this use laravel, here is an example code not tested,
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if (preg_match('account', $request->route()->getName()) { //if url is under account, you can get route info from $request->route();
if (!session()->get($token)) { // if not have valid token
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->route('admin.login.index',['referrer'=>urlencode($request->url())]);
}
}
} else {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->route('admin.login.index',['referrer'=>urlencode($request->url())]);
}
}
}
return $next($request);
}
then from your route just add middleware auth to your group, this is a way to define you request in on middleware, laravel 5.2 support mutiple middleware.

Resources