Laravel response download not working inside Route middleware and prefix - laravel

Route::group(['middleware' => ['role:0','auth']],function(){
Route::prefix('s')->group(function () {
Route::name('s.')->group(function ()
{Route::get('order/po/download/{item}', function($item = ''){
return response()->download(storage_path('app/public'.$item));
});
The routing URL will be like:
s/order/po/download/$item
The issue is everytime I access this url it will bounce to login page for no reason.
Can any help with this? It works in my local vagrant. However, when I push the project onto a live server, it always redirect to login even I have already logged in.
If I put it outside which is accessible for everyone before the Middleware Route (not the best solution but it works):
Route::get('order/po/download/{item}', function($item = ''){
return response()->download(storage_path('app/public'.$item));
});
Added Role middleware :-
public function handle($request, Closure $next,$role)
{
$user = Auth::user();
// Check if user has the role This check will depend on how your roles are set up
if($user->role_id == $role)
{
return $next($request);
}
else
{
return redirect()->back();
}
}
}

Related

Custom Auth Middleware not redirecting properly for unauthorized user

I have created a custom auth controller for recognising unauthorized user and redirect them to login path. If logged in the middlewre is working absolutely fine, but showing error if not logged in. Here is my code
Middleware:
class CheckUserAuthenticated
{
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
return redirect('login'); // this code is not working
}
}
Error:
try this hope it help
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
return redirect('/login'); OR return redirect(route('login'));
}
class CheckUserAuthenticated
{
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
// return redirect('login'); // this code is not working
return redirect()->guest('/login');
}
}
redirect()->guest() will redirect if there is no authenticated user.
Example: If an authenticated user is logged in, it won't redirect them as they aren't a guest. If a user isn't logged in, the redirect will happen.
The issue is in circular routing, you are calling from one route, and then return to the same route from the middleware, so your request never reaches the endpoint.
if you call middleware on the...
Route::get('login')->middleware('auth);
...then middleware can not route to 'login' on the fail...
return redirect('login');
... because it will create the loop that never ends. The middleware should reroute to something else, or be placed on other route like 'admin'...
You probably have the middleware on the 'login', that creates the loop, just remove it.

Protecting Routes With Two middle-wares So that both users can access it

I am trying to protect a route using two middle-wares so that both expert and user can access the same route but as soon a user tries to access the route he is logged out.
I had created two middle-wares for expert and user and protect the route using these middle-wares.
Web.php
Route::group(['middleware' => ['expert','user']], function () {
Route::post('/showForm','UserController#showFormFilled');
});
User Middle ware
public function handle($request, Closure $next)
{
//////////////////// check if user is logged in ///////////////////
if(Auth::check())
{
////////////////// check user role id //////////////////////////
if(auth()->user()->role_id == 3)
{
return $next($request);
}
else if (auth()->user()->role_id==2)
{
return redirect('/expert');
}
}
else
{
return redirect('/login');
}
}
Expert Middle ware
public function handle($request, Closure $next)
{
if(Auth::check()){
if(auth()->user()->role_id == 2)
return $next($request);
else if (auth()->user()->role_id==3)
return redirect('/dashboard');
}
else {
return redirect('/login');
}
}
Both the users should be able to access the same route.
#hamzahummam - there is no way to achieve what you are looking for using the above separate-middlware-for-each-type method. Each middleware prematurely redirects [either to /dashboard or to /expert etc] the request without allowing it to passthrough other middleware. Best would be to use a third-party package that provides a more comprehensive and fine-grained access control [example: https://github.com/Zizaco/entrust]
If that's not an option, the best case would be to implement a single middleware and pass the role as parameter. See: Laravel Middleware Parameters
A minimal example would look like:
public function handle($request, Closure $next, $role)
{
// Assuming Auth::check() passes
$roleId = auth()->user()->role_id;
if ($roleId == 2 && strpos($role, 'expert') !== false) {
// Logged in user is `expert` and route allows `expert` access
return $next($request);
} else if ($roleId == 3 && strpos($role, 'user') !== false) {
// Logged in user is `user` and route allows `user` access
return $next($request);
} // and so on...
// Handle failures here
if ($roleId == 2 && strpos($role, 'expert') === false) {
// an `expert` is trying to access route that can't be accessed
return redirect('/expert-dashboard');
} // and so on...
}
You'd define routes as:
Route::group(['middleware' => ['new_middleware:expert,user' ]], function () {
Route::post('/showForm','UserController#showFormFilled');
});
Hope this helps.

How to protect a route with middleware in laravel?

i have a problem with my middleware. when i login as admin, it's working fine and redirect to /Admin/home same as Operator (i have 2 user, Admin & Operator). The problem is when i hit url as example : /Operator/home as Admin role, it can access it. And that's the problem.
I'have create a new middleware CheckMiddleware, and registered to kernel in array $routeMiddleware as checkMiddleware:
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user) {
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
}
return dd('Forbidden page. you have to login as admin/operator');
}
In the route :
Route::group(['prefix'=>'Admin' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Route::group(['prefix'=>'Operator' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Auth::routes();
in User model :
public function isAdmin(){
if ($this->role_id === 1) {
return true;
}
return false;
}
public function isOperator(){
if ($this->role_id === 2) {
return true;
}
return false;
}
What i want is, Admin cannot access Operator and Operator Cannot Access Admin.
if this is not clear, tell me what file you want to see.
The problem is if user is admin then accept request and user is operator still accept request. That code below
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
For simple solution, just create two middleware for admin and operator. Then apply admin middleware for route (group) need admin role, and apply operator middleware for route (group) need operator role.
If you have some route allow admin and operator role access, just add both to that route.
UPDATE
If you want to use 1 middleware, do like this :
if ($user->isAdmin() && $request->route()->getPrefix() == 'admin') {
return $next($request);
}
if ($user->isOperator() && $request->route()->getPrefix() == 'operator') {
return $next($request);
}
return abort(401) // OR SOME ROUTE YOU WANT

Laravel - Use Middleware for restrict the user blocked profile?

I am working on a project in Laravel, it's a scratch of a social network. I have a important question. I have a controller with the profile of the user, there first of all i look if the user exists, if not exists it gets a 404, if exists get the data and the controller sends it to the view.
But now I was thinking that I can do a Blocking System between users. I created the table with N:n, were it's the user id who blocked and the user id of the destiny.
I made a Middleware to check if the users is blocked. But this middleware is executed on the route, and this means is executed before check if the user exists. It doesnt make me any problem. It's all working but my question is: This the best solution? It's better use a policy?
User Model
public function usersBlockedI()
{
return $this->belongsToMany(User::class, 'u_blocks', 'u_from', 'u_to');
}
u_blocks is the name of the table.
u_from is the name of the user who made the block.
u_to the user who received the block.
User Controller:
public function showProfile($username)
{
$profileUser = User::where('username', $username)->first();
if ($profileUser == null) {
return abort(404);
} else {
$profileUser['dataUser'] = dataUser::where('u_id', $profileUser['id'])->first();
return view('user.profile', compact('profileUser'));
}
}
Block Middleware
public function handle($request, Closure $next)
{
if (auth()->user()) {
$usernameProfile = $request->route('username');;
$ActualuserID = auth()->user()->id;
$checkIfBlocked = User::where('username', $usernameProfile)->first()->usersBlockedI->where('id', $ActualuserID);
if (!sizeof($checkIfBlocked) == 0) {
abort(404);
}
}
return $next($request);
}
Routes
Route::group(['middleware' => 'blocked'], function () {
Route::get('/{username}', 'UserController#showProfile')->name('showProfile');
});

Laravel 5.2 Authentication error: Accessing logged in page directly through URL

I am using Laravel 5.2 and I have Authenticate.php file in:
\vendor\laravel\framework\src\Illuminate\Auth\Middleware
I need to authenticate my user so that, the user can't access the logged in page by just writing it in URL. How to do it?
When I searched, the solutions were for the Authenticate file which was in Middleware folder inside Http, which was a little different.
Please tell me how to do it. I tried:
if(Auth::guard($guard) -> guest()){
if ($request -> ajax()){
return response['Unauthorized',401];
} else{
return redirect() -> guest('login');
}
}
return $next($request);
}
}
How to do it? please tell me options. Any suggestion is invited.
And, Thank you in advance... :)
The solutions you found while searching are correct, you should actually edit your middlewares inside app/Http/Middleware if you checked out the documentation here, the right way to do it is:
You have to update this middleware app/Http/Middleware/RedirectIfAuthenticated.php which has this function
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
return $next($request);
}
What you can do in your case, you can use the same if clause in your current handle function, so it looks like this:
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
return response['Unauthorized',401];
} else {
return redirect()->guest('login');
}
}
return $next($request);
Put all the routes that only the logged in users can access into Auth Middleware group:
Route::group(['middleware' => ['auth']], function () {
// Routes here
});

Resources