Check Auth::user() from middleware - laravel

I try to check in middleware if user is authenticated by calling Auth::user()
But it returns null. I call this middleware last in list of protected $middleware section in Kernel.php. Is there an way to check from middleware if user is authenticated or how I should do it another way?
Addition: I'm using Zizaco Entrust. May be it is why it doesn't work
And I'm using Laravel 5.5
my app/HTTP/Kernel.php:
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\FirstLoginPasswordChange::class,
];
my FirstLoginPasswordChange middleware:
use Illuminate\Support\Facades\Auth;
use Zizaco\Entrust\Entrust;
public function handle($request, Closure $next)
{
dd(Auth::user()); // returns null
// or
dd(Auth::check()); // returns false
// or
dd(\Entrust::user()); // returns null
return $next($request);
}
}

problem solved by moving middleware from protected $middleware section in Kernel.php to protected $routeMiddleware section in Kernel.php
using this article:
http://laraveldaily.com/password-expired-force-change-password-every-30-days/

To check if user is authenticated you can do as Laravel Docs states:
use Illuminate\Support\Facades\Auth; //be sure to add the facade
if (Auth::check()) {
// The user is logged in...
}
If you are trying to get user details and do some logic, then you can do this in your middleware:
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$role = Auth::user()->role; //Obtenemos el rol del usuario
if ($role != "user"){
return redirect('/logout');
}
return $next($request);
}
}

Related

Laravel not changing language

Laravel is not changing the language I have tried these methods in controller
if ($request->lang === 'English') {
config(['app.locale' => 'en']);
} else {
config(['app.locale' => 'ar']);
}
and this method
App::setLocale('ar')
Or this method
\App::setLocale('ar')
What should I do?
You can create a middleware that puts the locale in the session and sets it.
php artisan make:middleware SetLocale
app\Http\Middleware\SetLocale.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
class SetLocale
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
if ($request->input('lang') == 'English') {
$request->session()->put('locale', 'en');
} else {
$request->session()->put('locale', 'ar');
}
App::setLocale($request->session()->get('locale'));
return $next($request);
}
}
Then, add it to your global middleware (or to a middleware group).
app\Http\Kernel.php
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
// other global middlewares
\App\Http\Middleware\SetLocale::class,
];

Single API use for authenticated and guest user

My laravel application route configured on routes/api.php is.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
Issue is i want to sent list of product but if user authenticated then send product favorite flag 1, and if not authenticated then send return favorite 0
But both case send product list with favorite flag.
If i logged in with my user id and password and send request for see_all_product that time i m getting blank user.
$user = $request->user();
But if i set route like below i m getting user details.
<?php
use Illuminate\Http\Request;
Route::group(['middleware' => 'auth:api'], function(){
Route::post('see_all_product', 'API\ProductController#see_all_product');
});
?>
Now issue is how can i get details if authorization set in the header with same api.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
My see_all_product Function
public function see_all_product(Request $request){
try {
$user = $request->user();
} catch (Exception $ex) {
Log::error($ex);
}
}
API is same for both authenticated and guest user.
I pass authorization token in both case but middleware route i get user details but non middleware route i dont get user information.
Please guide me where i can miss something?
I think you can do it by the way instead of $request->user():
if (auth('api')->check()) {
$user = auth('api')->user();
}
Turn off ['middleware'=> 'auth:api']
use: $request->user('api'); in your controller.
Guests can use the api but user is null;
Auth users can use api as a real user.
alt:
Auth::guard('api')->user();
auth('api')->user();
I didn't test this method on old versions of Laravel, but it should work just fine on the latest ones.
You can create another Middleware that allows ether authenticated or guest users to proceed.
If the user is authenticated then the middleware will prepare the Auth object and auth() function for you.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
class AuthOptional
{
/**
* The authentication factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$this->authenticate($request, $next, $guards);
return $next($request);
}
/**
* Determine if the user is logged in to any of the given guards.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function authenticate($request, $next, array $guards)
{
if (empty($guards)) {
$guards = [null];
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
//If unauthenticated allow the user anyway
$this->unauthenticated($request, $next, $guards);
}
/**
* Handle an unauthenticated user.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function unauthenticated($request, $next, array $guards)
{
return $next($request);
}
}
Import the newly created Middleware under app/Http/kernel.php
protected $routeMiddleware = [
....
'auth.optional' => \App\Http\Middleware\AuthOptional::class
];
And finally use it like this:
<?php
Route::group(['middleware' => ['auth.optional:api']],
});
?>
Now auth()->user() will return the user if user is authenticated and
null if it's not

Laravel Global Middleware Detected but Not Altering Model Records

I have the following middleware (LastSeen):
<?php
namespace App\Http\Middleware;
use Closure;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\Factory as Auth;
class LastSeen
{
/**
* The authentication factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
$user = $this->auth->user();
$user->last_activity = Carbon::now();
$user->save();
}
return $next($request);
}
}
This was mostly taken from this answer ( Check if user online laravel ) as a stop-gap solution to a project I am working on.
I do have a TIMESTAMP column in my users table labeled last_activity and this is my Kernel file global middleware:
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\App\Http\Middleware\LastSeen::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\ModifyHeadersMiddleware::class,
];
I'm not sure where to go next, I am just beginning on middleware and am still learning but not sure what I'm doing wrong...
Thanks!
The problem is that info about authorized user is stored in session and LastSeen's auth check is running before session was started so it allways return false.
You need to move LastSeen middleware after StartSession middleware:
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\LastSeen::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
There are some issues, but the main mistake is you are calling the wrong Auth. You have to call the facade, you are calling the Auth factory. Another thing is, avoid the constructor. Keep it simple. Especially for MiddleWare. One last thing, you are updating the user status, not saving a new entry.
namespace App\Http\Middleware;
use Closure;
use Carbon\Carbon;
use Auth;
class LastSeen
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::check()) {
$user = Auth::user();
$user->last_activity = Carbon::now();
$user->update();
}
return $next($request);
}
}

In My Laravel Passport Application, how can I accept access_tokens (when the client does not send a Bearer header)

I am using an OAuth2 client that does not send Authorization: Bearer but the standard laravel/passport setup checks this header. How to make it compatible from Laravel side?
Add the following middle ware
<?php
namespace App\Http\Middleware;
class ConvertTokenToBearer
{
/**
* #param \Illuminate\Http\Request $request
* #param $next
*
* #return \Symfony\Component\HttpFoundation\Response
*/
public function handle($request, $next)
{
if ($request->get('access_token')) {
$request->headers->set('Authorization', 'Bearer ' . $request->get('access_token'));
}
$response = $next($request);
return $response;
}
}
And add it to your app/Http/Kernel.php file.
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\ConvertTokenToBearer::class,
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];

Middleware and user - laravel 5

How can i assign middleware to user? I just follow the guide on laravel 5.2 but i can't figure...
I'm able to create middleware ( i have admin middleware)
<?php
namespace App\Http\Middleware;
use Closure;
class Admin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
I'm able to assign middleware to route
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::resource('admin/tasks', 'Admin\\TasksController');
});
but how can i check if user is admin or not? I just follow the docs on laravel 5.2 for authentication, but i dont know how to access the page only for "admin" middleware...
Question 1 How to check if user is admin
I think using session is a good solution. You can store the user status in the session. And in the Admin middleware, you can check if user is admin by if (session('statut') === 'admin').
Question 2 Page Access of users
If user is admin, we will pass the request by return $next($request);
If user is not admin, we will redirect to index page or other page
you want by return new RedirectResponse(url('/'));
The following code may help you.
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\RedirectResponse;
class Admin {
public function handle($request, Closure $next)
{
if (session('statut') === 'admin')
{
return $next($request);
}
return new RedirectResponse(url('/'));
}
}
I would recommend you to use ENTRUST Laravel package
Entrust is a succinct and flexible way to add Role-based Permissions
to Laravel 5.
I have a small example for you, it very simple
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class Authenticate
{
/**
* The authentication guard factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
}
If you only have guest and admin(who is authenticated in your system) you should do like above. But if you have another roles you will have to attach ACL (for ex https://github.com/Zizaco/entrust)

Resources