I'm using Laravel 5.1 and am creating a "Admin" middleware to check that a user has right to access a specific page.
I would like to do this, but it doesn't work:
public function handle($request, Closure $next)
{
if ($this->auth->guest() or !$this->auth->user()->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}
So I achieve my goal like this, but it seems weird:
public function handle($request, Closure $next)
{
if ($this->auth->guest() or ! User::find($this->auth->user()->id)->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}
Any suggestion? Am I missing something?
I don't know but if you copied your code
!$this->auth->user-()->isAdmin()
, is error. After user you have "-()"
OKay, thank you for your help:
I had two User class (one in App\User and one ine App\Models\User). I changed my configuration in config/auth.php to set the model to App\Models\User::class and deleted the default User model present when installing Laravel. So now the isAdmin() function works.
And as xAoc told me, the code is now the following:
public function handle($request, Closure $next)
{
if (!$this->auth->user()->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}
Related
I'm using Laravel 8 for my project and in this project and I have created a custom Middleware called Admin that goes like this:
public function handle(Request $request, Closure $next)
{
if (Auth::user()->isAdmin()) {
return $next($request);
}
return redirect('/');
}
And I tried applying it like this:
Route::middleware('admin')->group(function () {
Route::get('test', function () { return "User is authenticated and is an admin."; });
});
And on Kernel.php at $middlewareGroups section:
'admin' => [
'auth',
\App\Http\Middleware\Admin::class
],
So I called the isAdmin() at User Model which simply checks if the role of the user is correct or not:
public function role()
{
return $this->belongsTo(Role::class);
}
public function isAdmin()
{
return $this->role->contains('slug', 'super-admin');
}
But now the problem is, when I go to /test uri, it does not redirect me to ('/') uri and shows me this error:
BadMethodCallException
Call to undefined method App\Models\Role::contains()
So what is going wrong here? How can I fix this issue?
Note that the relationship between roles and users table is One To Many. That's why I wrote role() instead of roles() because each user has only one role.
When you use a belongsTo relationship, laravel will return the model directly and not a collection of models.
When you call:
$this->role
What you get is either null (if the relationship does not exist) or a Role model. You can write your isAdmin function accordingly:
public function isAdmin()
{
return empty($this->role) ? false : $this->role->slug === 'super-admin';
}
You probably copied the code from an example with a Many to many relationship: in that case Laravel will return a collection of models and you can invoke collection methods on it, such as contains
could we see a snip of your Role Model.
For whatever reason, my AuthServiceProvider has stopped working. It looks like the $request parameter being passed to the closure for viaRequest is not seeing the request input. If I send JSON with a key of "access_token" to any of my endpoints and try and var_dump it in the closure - it only returns null. Here is the code for the boot method:
public function boot()
{
$this->app['auth']->viaRequest('api', function ($request) {
var_dump($request->input('access_token'));
});
}
And here is my auth middlewares handle method:
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
Any help is greatly appreciated since I am pulling my hair out right now.
EDIT Looks like the issue is with Sentry and their user_context setting be set to true. As soon as I set it to false, the requests come through perfectly
Issue turned out to be Sentry's user_context setting being set to true. Setting it to false fixed the issue.
I have a Middleware for Admin login where i am checking whether is user is admin or not. But now i want to check if an admin have permission to access the page or not. How can i do that?
My AdminMiddleware is:
public function handle($request, Closure $next)
{
if(Auth::check())
{
$user = Auth::user();
if($user->user_type=='employee')
{
return $next($request);
}
else
{
return redirect('/');
}
}
else
{
return redirect('/');
}
}
One way is to add the following code to each and every function of every controller.
if(Auth::user()->permission=='manage_employee'){
//code here
}
else
{
//redirect to access denied page
}
But this is not the correct way and time consuming. Is there any other way without using packages?
This is the proper way to use your middleware
Route::get('/your-url', 'YourController#yourFucntion')->middleware('admin');
Where admin is the name you register your middleware in your Kernel.php file :
to register it you have to insert this in $routeMiddleware part
'admin' => MustBeAdministrator::class,
If you wan to have different kind of admin check you can edit your route to pass a variable:
->middleware('admin:employee');
and you can get this variable in your middleware like this:
enter this below the comment #param \Closure $next :
#param string $permition
and modify your function:
public function handle($request, Closure $next, $permition)
Then use your permition variable in an if statement to do whatever you want to do.
Is there any way to access (modify) $request "protected proprieties" in the Middleware, to modify requested Controller:
public function handle($request, Closure $next)
{
// change $request parameter
// $request->server->parameters->REQUEST_URI = "something else";
return $next($request);
}
I want to override requested Controller if Cache is valid for the request,
thanks,
You can change the page in the middleware by returning a redirect.
public function handle($request, Closure $next)
{
// change $request parameter
// $request->server->parameters->REQUEST_URI = "something else";
if ($request->something === 'anything')
return redirect()->to("/something-else");
return $next($request);
}
Update:
If you do not wish for the url to update, you could invoke the controller directly using:
app(\App\Http\Controllers\MyController::class)->getMethod();
Where you update the Controller and the method to the ones you need.
However I would not recommend this.
I am using multiple views for the same URL, depending if the user is logged in or not.. so mywebsite.com is routed like this:
Route::get('/', 'HomeController#redirector')->name('home');
The controller is this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
return $this->index();
}
}
Now, when it runs the index function I need it to run the middleware 'auth', that updates and checks the user. The problem is, I cannot attach it to the route, since they might be unlogged causing a redirection loop. I tried this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
$this->middleware('auth');
return $this->index();
}
}
It does not run the middleware.
If I put it in the costructor method attaching it to index, like this:
$this->middleware('auth', ['only' => 'index'])
it also won't run.
Any solutions to this?
if(!\Auth::check()){..} //this returns false if a user is logged in, are you sure that's what you want?
If not then remove the '!'
You can also put the redirection logic in the middleware instead. If you are using the auth middleware that ships with Laravel this is already in place. You just have to modify it as below and place the middleware call in the constructor.
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
return redirect()->guest('login');
}
return $next($request);
}