I put myRoute inside the auth middleware group and I get
// myController
Auth::guard('web')->user() // null
I dont know what to do.. I have controllers and routes below.
Seems like parent controller constructor is working but the middleware is not.
// Controller.php
public function __construct() {
$this->middleware(function ($request, $next) {
$this->currentUser = Auth::guard('web')->user();
return $next($request);
});
}
// myController extends Controller
public function __construct(Request $request) {
parent::__construct();
$this->request = $request;
var_dump($this->currentUser); // null
var_dump(Auth::guard('web')->user); // null
// $userId = Auth::guard('web')->user()->id;
// $userId = $this->currentUser->id;
$this->userId = $userId;
}
// route/web.php
Route::middleware(['auth'])->group(function () {
Route::get('myRoute', 'myController#index');
}
You can't get the Auth::user() in constructor. try Auth::guard('web')->user(); in another method. The result is not null anymore
Related
I have a class like this:
class BaseApiController extends Controller
{
protected $user;
function __construct()
{
$this->configHeaderRequest();
$this->validateToken();
}
protected function validateToken()
{
$this->middleware(function ($request, $next) {
if (Auth::guard('web')->user()) {
$this->user = Auth::guard('web')->user();
}
var_dump($this->user); //=> This is "user object" as well
return $next($request);
});
}
}
And another class that is extended from the class above:
class NewsController extends BaseApiController
{
public function __construct(Request $request)
{
parent::__construct($request);
$this->middleware(function ($request, $next) {
if (empty($this->user)) {
return $this->sendFailedResponse('Unauthorized Request', 401);
}
return $next($request);
});
}
public function search(Request $request): JsonResponse
{
var_dump($this->user); //=> but there is "null"
}
}
As you can see, $this->user will be null when I needed the user's object inside the search(Request $request) method while surprisingly the user's object exists inside the validateToken() method. Why? And how can I access the user's object there?
//here is my route
Route::get('/works', function () {
$works=Work::all();
return view('works',compact('works')); })->middleware('IsAdmin');
});
here is my IsAdmin function in User Model
public function roles(){
return $this->belongsToMany('App\Role','user_role','user_id','role_id');
}
public function IsRole(){
return $this->roles;
}
And this is my IsAdmin middleware
public function handle($request, Closure $next)
{
$user=Auth::user();
if($user->IsRole()->name=='Administrator'){
return true;
}
}
why it give me undefined method error?
do you register your middleware inside app/Kernel.php into $routeMiddleware array.
Should be something like that
protected $routeMiddleware = ['check.admin' => \App\Http\Middleware\YourClass::class]
I am seeing some behaviour. I can't explain when accessing user data via the Auth facade in Laravel class. Here's an extract of my code:
private $data;
private $userID;//Set property
function __construct()
{
$this->middleware('auth');//Call middleware
$this->userID = Auth::id();//Define property as user ID
}
public function index() {
return view('');
}
public function MyTestMethod() {
echo $this->userID;//This returns null
echo Auth::id();//This works & returns the current user ID
}
I am logged in and have included use Illuminate\Support\Facades\Auth; in the class thus the code works, but only when accessing Auth in methods - else it returns a null value.
Most odd, I can't work out what is causing this. Any thoughts much appreciated as ever. Thanks in advance!
In Laravel Laravel 5.3.4 or above, you can't access the session or authenticated user in your controller's constructor, since the middlware isn't runnig yet.
As an alternative, you may define a Closure based middleware directly in your controller's constructor.:
try this :
function __construct()
{
$this->middleware(function ($request, $next) {
if (!auth()->check()) {
return redirect('/login');
}
$this->userID = auth()->id(); // or auth()->user()->id
return $next($request);
});
}
another alternative solution go you your base controller class and add __get function like this :
class Controller
{
public function __get(string $name)
{
if($name === 'user'){
return Auth::user();
}
return null;
}
}
and now if your current controller you can use it like this $this->user:
class YourController extends Controller
{
public function MyTestMethod() {
echo $this->user;
}
}
You should try this :
function __construct() {
$this->userID = Auth::user()?Auth::user()->id:null;
}
OR
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->userID = Auth::user()->id;
return $next($request);
});
}
I have a controller like this:
public function __construct()
{
$check = Auth::id();
if ($check->role == '5') {
// allow to run any other controller
} else {
// return view('home')
}
return $check;
}
public function index()
{
return view('admin.home');
}
What I want to do is whenever, AdminController is triggered, run __construct function and check if role == 5, if it is, proceed with the request, else return view. How can that be done?
Edit
public function handle($request, Closure $next)
{
if ($request->role == 2) {
} else {
return view('index');
}
return $next($request);
}
Kernel:
protected $middlewareGroups = [
'admin' => [
\App\Http\Middleware\CheckAdmin::class,
],
];
Route:
Route::group(['middleware' => ['admin']], function () {
Error::
(1/1) FatalThrowableError Call to a member function setCookie() on
null in VerifyCsrfToken.php (line 156)
view() returns a Illuminate\View\View object, instead of a Illuminate\Http\Response. So instead of sending the view. Redirect the user to index route
Try this
public function handle($request, Closure $next)
{
if ($request->role != 2) {
return return redirect()->route('index');
}
return $next($request);
}
I have a middleware that authenticates a JWT user using tymon/jwt-auth package:
public function handle($request, \Closure $next)
{
if (! $token = $this->auth->setRequest($request)->getToken()) {
return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
}
try {
$user = $this->auth->authenticate($token);
} catch (TokenExpiredException $e) {
return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
} catch (JWTException $e) {
return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
}
if (! $user) {
return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
}
$this->events->fire('tymon.jwt.valid', $user);
return $next($request);
}
Then I have a controller and I want to pass the user from the middleware to the controller.
So I did on the controller:
public function __construct()
{
$this->user = \Auth::user();
}
The problem is that $this->user is null, but when I do this on a method of the controller, it's not null.
So:
public function __construct()
{
$this->user = \Auth::user();
}
public function index()
{
var_dump($this->user); // null
var_dump(\Auth::user()); // OK, not null
}
So the issue is that __construct is running before the middleware. How can I change that, or do you have another solution?
Update: I'm using dingo/api for routing, maybe it's an error on their side?
You should use the middleware(s) in the routes
Route::middleware('jwt.auth')->group(function() {
// your routes
});
1) Remove Your middleware from Your kernel's $middleware array
2) Put Your middleware to $routeMiddleware array with custom name jwt.auth:
protected $routeMiddleware = [
// ...
'jwt.auth' => 'App\Http\Middleware\YourAuthMiddleware'
];
2) Create BaseController in parent directory of needle controller, with function:
public function __construct() {
$this->middleware('jwt.auth');
}
3) Extend needle controller from BaseController
4) Make __construct function of needle controller to look like this:
public function __construct() {
parent::__construct();
$this->user = \Auth::user();
}