Related
Hi I am working on laravel project , I have to check about user's permission when he trying to access one page , my problem is after I created Permission middle ware , and add it in the kernel.php , it checking about permissions for all route even I did not call it in any route .
I don't want to apply this middleware on all route , just some of it .
this is my permission middleware's code
namespace App\Http\Middleware;
use Closure;
use Session;
use App\Rules;
use Illuminate\Support\Facades\Route;
use URL;
class Permissions
{
public function handle($request, Closure $next) {
$rolename=Session::get('rule_name') ;
$route = $request->path();
$hasPermission = Rules::where('rule_name', 'superadmin')->where('allowed_pages', 'like', '%' . $route . '%') ->first();
if (empty($hasPermission)) {
echo 'Unauthorized.Go Back';
die();
}
}
}
}
and this is my route file
Route::resource('Login', 'LoginController')->name('index','Login');
Route::resource('Backup', 'BackupController')->name('index','Backup');
as you see I did not apply the middleware on these tow route , but the middleware is working with these tow routes
this is my kernel code
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'Permissions' => \App\Http\Middleware\Permissions::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
I want to run this middleware only by route like this
Route::group(['middleware' => 'permissions'], function () {
Route::resource('Backup', 'BackupController')->name('index','Backup');
}
thank you for advance
best regards
You added your middleware to the middelwareGroup web, wich applies the middleware to every request comming in.
You need to add your middleware to the routes middleware array: docs
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
...
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
// your own middlewares:
'Permissions' => \App\Http\Middleware\Permissions::class,
];
You can than apply the middleware to specific routes:
Route::resource('Login', 'LoginController')->middleware('Permissions')->name('index','Login');
you added inside web which is default middleware by laravel that's why it's applied in all route.
to register a middleware you need to add in protected $routeMiddleware = [ ] array
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
//custom middlewares:
'Permissions' => \App\Http\Middleware\Permissions::class,
];
then only
Route::group(['middleware' => 'permissions'], function () {
Route::resource('Backup', 'BackupController')->name('index','Backup');
}
it will work
I want to make authentication for API requests coming from mobile users.
I followed this
and made api_key column inside users table.
I also created middleware:
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
return $next($token);
}
What I want is to get bearer token from header and check it against user table.
How to achieve this?
Append the auth:api middleware to any route or group of routes and the Bearer token will be checked automatically for you without a custom middleware
Route::get('url', 'controller#method')->middleware('auth:api');
But to answer the question, here's what you can do (still not recommended but works)
<?php
namespace App\Http\Middleware;
use Closure;
class ApiAuthentication
{
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
$user = \App\User::where('api_token', $token)->first();
if ($user) {
auth()->login($user);
return $next($request);
}
return response([
'message' => 'Unauthenticated'
], 403);
}
}
Register the middleware in App\Http\Kernel
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
// Here for example
'custom_auth' => \App\Http\Middleware\ApiAuthentication::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
And protect a route with that middleware name
Route::get('/', function () {
// Return authenticated user model object serialized to json
return auth()->user();
})->middleware('custom_auth');
Result
I would recommend laravel/passport as it is much secure and easier.
Click Here.
I'm trying to send a post request from my frontend ( Ionic ) to my backend Laravel ! it return that Cors error. I've already made the Cors class in Laravel and added it the routeMiddleware, I have also tried the solution made by barryvdh and it's also not working. when I try the request using the get method it works but it's not the same case while using post method.
here my handle method in Cors class in laravel :
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: *");
// ALLOW OPTIONS METHOD
$headers = [
'Access-Control-Allow-Origin'=> '*',
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];
if($request->getMethod() == "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}
middleware array in Kernel.php
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Cors::class,
];
api part of the middlewareGroups array in Kernel.php
'api' => [
'throttle:60,1',
'bindings',
\App\Http\Middleware\Cors::class,
]
routeMiddleware array in Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'jwt.auth' => Tymon\JWTAuth\Http\Middleware\Authenticate::class,
'jwt.refresh' => Tymon\JWTAuth\Http\Middleware\RefreshToken::class,
'cors' => \App\Http\Middleware\Cors::class,
];
The route I'm trying to call
Route::post('auth/login', 'ApiController#login');
Here the code I'm executing in ionic
login(emaill: string, passwordd: string) {
return this.http.post<any>(
`${environment.laravelBackend}/auth/login`,
{ email: emaill, password: passwordd}
);
}
Anyone knows how I can make this work ?
Thanks in advance
there may be 2 solutions try both if first or second does not work.
1) Sometime, it not works due to the developer's composer version where the API is made, and the machine where you have setup the environment's composer version is different. check it. and if possible, send your and the machine where api is developed's composer version.
2) Add CORS in .htaccess File like this
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"
Header set Access-Control-Allow-Credentials "true"
I'm about to create a single-sign-on interface for my app. The other app sends an AJAX POST request and I authenticate the user and return a response. A session cookie is beeing set, but it is not encrypted.
The relevant Code
$user = User::where('email', $email)->first();
if ($user) {
Auth::login($user);
return response("OK", 200);
}
My 'api' part in Kernel.php
'api' => [
'throttle:60,1',
'bindings',
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\App\Http\Middleware\EncryptCookies::class,
],
My route (no additional Middleware)
Route::post(
'/auth-request', [
'uses' => 'UserController#post_authenticateRequest',
'as' => 'authrequest'
]);
The EncryptCookies class in Kernel.php doesn't seem to have any effect in the AJAX post request - but only for the session part. When I manually add a cookie like
response("OK", 200)->cookie("mysession", Session::getId(), 60);
it is encrypted!
When I completely remove EncryptCookies in Kernel.php for both "api" and "web" the created session from the AJAX request is loaded correctly - but without encryption anymore.
How do I get the AJAX session cookie beeing encrypted? Do I need any other Middleware?
Thanks for your help.
After reading the comment from lagbox, I've tried several places for the EncryptCookies::class definition in my "api" part. I need to place it not only before StartSession but as the first element. And now it works!
My complete $middlewareGroups part in Kernel.php now looks like this:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\App::class,
],
'api' => [
\App\Http\Middleware\EncryptCookies::class,
'throttle:60,1',
'bindings',
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
],
];
Hope this is helpfull.
I have laravel 5.0 . and set sessions drivers to database . I have some link that no require to insert new row in sessions table . how i can disable inserting new row only for www.site.com/download .
Create a new route/middleware type for sessionless access. Do this by adding a new middleware group in your Http/Kernel that doesn't include the StartSession middleware, then adding a new route file to hold all your download links, and then registering your new route file in your RouteServiceProvider.
Edit the $middlewareGroups array in app/Http/Kernel.php to look like the following:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
'sessionless' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Then edit your app/Providers/RouteServiceProvider to map your newly-created route file:
Route::group([
'middleware' => 'sessionless',
'namespace' => $this->namespace,
'prefix' => 'download',
], function ($router) {
require base_path('routes/downloads.php');
});
Now add a file in your /routes directory named downloads.php, and add your downloadable routes there. If you want to use a wildcard to parse what file they're looking for, you can, or you can explicitly list what routes will trigger a download:
Route::get('test', function(){
$file = '/path/to/test/file';
return response()->download($file);
});
Route::get('{fileName}', function($fileName){
$file = '/path/to/' . $fileName;
return response()->download($file);
});
This doesn't address using headless authorization, which you would need if you didn't want unauthorized access to all of your sessionless routes.
this solution is good for laravel 5.0
first must define two middleware in app/http/kernel.php .first middleware is lesssession . lesssession is for route that do not need session .and second is hasssession middleware .hassession is good for route that need session :
<?php namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel {
/**
* The application's global HTTP middleware stack.
*
* #var array
*/
/**
* The application's route middleware.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'hassession' => [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
],
'lesssession' => [] ,
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
];
}
step 2:
put route in two group by edit app/http/route.php:
<?php
Route::group(['middleware' => ['lesssession']], function()
{
Route::get('download', function(){
// do some stuff for download file
});
});
Route::group(['middleware' => ['hassession']], function()
{
// all other route that need session
});
?>