I have tried injecting the Guard contract into the constructor, I have tried moving around. But when a user is logged in - Auth::check() returns false.
In other files (Except 1 global middleware) Auth::check() works correctly.
In the middleware - moving Auth Check to the top helped alleviate the issue. In this case - it isn't working.
Additional information: This app has been upgraded from 4.2 . Previously it used Confide.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
if(Auth::check())
{
$user = Auth::user();
$messages=Message::where('read',0);
$messages->where(function ($query) use ($user) {
$query->where('to',$user->id)->orwhere('from',$user->id);
});
$message_unread= $messages->count();
$new_notifications= Notification::where('user_id',$user->id)->where('viewed',0)->count();
}
else
{
$message_unread=0;
$new_notifications=8888888;
//its 888888 for testing purposes.
}
view()->share(([
'message_unread'=>$message_unread,
'new_notifications'=>$new_notifications
]));
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
You should move this code to controller layer. boot method of Laravel's ServiceProviders serves for bootstrapping the services, not implementing busines logic.
You need to use auth in at the top of the serviceprovider class
use Auth;
Instead of
use Illuminate\Support\Facades\Auth;
Apart from using a view composer, you could also use middleware which is processed after the session variables have been loaded:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class SetViewVariables
{
protected $auth;
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
$user = $this->auth->user();
view()->share('user', $user);
return $next($request);
}
}
Related
I'm using Laravel 5.3 and I'm trying to get the authenticated user's id in the constructor method so I can filter the user by assigned company as follows:
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\View;
use App\Models\User;
use App\Models\Company;
use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests ;
public $user;
public $company;
public function __construct()
{
$companies = Company::pluck('name', 'id');
$companies->prepend('Please select');
view()->share('companies', $companies);
$this->user = User::with('profile')->where('id', \Auth::id())->first();
if(isset($this->user->company_id)){
$this->company = Company::find($this->user->company_id);
if (!isset($this->company)) {
$this->company = new Company();
}
view()->share('company', $this->company);
view()->share('user', $this->user);
}
}
However this doesn't return the user id. I've even tried Auth::check() and it doesn't work.
If I move the Auth::check() out of the __construct() method then this works as follows:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
dd(\Auth::check());
return view('home');
}
}
However this fails if I put this in the construct method in the HomeController too!
Any ideas why this is failing?
docs
you can't access the session or authenticated user in your
controller's constructor because the middleware has not run yet.
As an alternative, you may define a Closure based middleware directly
in your controller's constructor. Before using this feature, make sure
that your application is running Laravel 5.3.4 or above:
class ProjectController extends Controller
{
/**
* All of the current user's projects.
*/
protected $projects;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->projects = Auth::user()->projects;
return $next($request);
});
}
}
Since 5.3 Auth::check will not work in a controller's construtor, it's one of undocumented changes. So, you need to move it to middleware or do check in controller methods instead or move project to 5.2.x.
It fails because you call $this->middleware('auth'); after parent::__construct();. It means that you auth middleware is not loaded properly.
I created middleware: php artisan make:middleware CheckUserStatus
In this middleware I have:
namespace App\Http\Middleware;
use Closure;
class CheckUserStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth()->check() AND Auth()->user()->status === 0) { // user is logged in but it is blocked
auth()->logout();
return redirect('/');
}
return $next($request);
}
}
Then, one of my controller I have:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Middleware\CheckUserStatus;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware('CheckUserStatus');
}
}
This gives ReflectionException - Class CheckUserStatus does not exist
What I'm doing wrong ?
You need to register your middleware if you want to reference it by a string key. Check out the docs here.
Alternatively, you could use the fully qualified class name: try CheckUserStatus::class instead of 'CheckUserStatus'.
You need to use the fully qualified class name:
Either:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware('\App\Http\Middleware\CheckUserStatus');
}
}
or
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Middleware\CheckUserStatus;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware(CheckUserStatus::class); //No quotes
}
}
You need to add your middleware in kernel.php
protected $routeMiddleware = [
'your_desire_name'=>\App\Http\Middleware\CheckUserStatus::class,
];
I'm trying to share a collection of notifications to all views under the auth middleware. I thought I might be able to just call Auth::check() but it seems to always return false?
<?php
namespace App\Providers;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
use Auth;
class ViewServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
* #return void
*/
public function boot()
{
view()->composer('*', function ($view)
{
$view->with('userNotifications', Auth::user()->notifications);
});
}
}
I'm using Laravel 5.3 and I'm trying to get the authenticated user's id in the constructor method so I can filter the user by assigned company as follows:
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\View;
use App\Models\User;
use App\Models\Company;
use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests ;
public $user;
public $company;
public function __construct()
{
$companies = Company::pluck('name', 'id');
$companies->prepend('Please select');
view()->share('companies', $companies);
$this->user = User::with('profile')->where('id', \Auth::id())->first();
if(isset($this->user->company_id)){
$this->company = Company::find($this->user->company_id);
if (!isset($this->company)) {
$this->company = new Company();
}
view()->share('company', $this->company);
view()->share('user', $this->user);
}
}
However this doesn't return the user id. I've even tried Auth::check() and it doesn't work.
If I move the Auth::check() out of the __construct() method then this works as follows:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
dd(\Auth::check());
return view('home');
}
}
However this fails if I put this in the construct method in the HomeController too!
Any ideas why this is failing?
docs
you can't access the session or authenticated user in your
controller's constructor because the middleware has not run yet.
As an alternative, you may define a Closure based middleware directly
in your controller's constructor. Before using this feature, make sure
that your application is running Laravel 5.3.4 or above:
class ProjectController extends Controller
{
/**
* All of the current user's projects.
*/
protected $projects;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->projects = Auth::user()->projects;
return $next($request);
});
}
}
Since 5.3 Auth::check will not work in a controller's construtor, it's one of undocumented changes. So, you need to move it to middleware or do check in controller methods instead or move project to 5.2.x.
It fails because you call $this->middleware('auth'); after parent::__construct();. It means that you auth middleware is not loaded properly.
I am trying to use Laravel's HTTP Basic Authentication in a Lumen project.
On the routes.php file, I set the auth.basic middleware for the rout I need to authenticate:
$app->get('/test', ['middleware' => 'auth.basic', function() {
return "test stuff";
}]);
On bootstrap.php I have registered the middleware and the auth service provider:
$app->routeMiddleware([
'auth.basic' => Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
]);
[...]
$app->register(App\Providers\AuthServiceProvider::class);
But when I try to test the route by visiting http://lumen/test I get the following error:
Fatal error: Call to undefined method Illuminate\Auth\RequestGuard::basic() in C:\source\lumen\vendor\illuminate\auth\Middleware\AuthenticateWithBasicAuth.php on line 38
Does anyone know how can I get the code of the guard for basic authentication?
Thanks.
Ran into a similar problem, wanted to use basic auth for users in the database, so ended up writing my own AuthServiceProvider and registered that in bootstrap/app.php
Here is the class, maybe it will help you in your case.
<?php
namespace App\Providers;
use App\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\ServiceProvider;
class HttpBasicAuthServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Boot the authentication services for the application.
*
* #return void
*/
public function boot()
{
$this->app['auth']->viaRequest('api', function ($request) {
$email = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
if ($email && $password) {
$user = User::whereEmail($email)->first();
if (Hash::check($password, $user->password)) {
return $user;
}
}
return null;
});
}
}