routing in laravel with multiple htaccess - laravel

I want specific htaccess file for specific route.
For example, i want to allow all ips to home route of my site but prevent access specific ips to just payment route or specific routes.
Please help me with this problem.

you can use three solution:
laravel middleware
code Source
here:
namespace App\Http\Middleware;
use Closure;
use Symfony\Component\HttpFoundation\IpUtils;
class RedirectInvalidIPs
{
protected $ips = [
'65.202.143.122',
'148.185.163.203'
];
protected $ipRanges = [
'10.11.3.1',
];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
foreach ($request->getClientIps() as $ip) {
if (! $this->isValidIp($ip) && ! $this->isValidIpRange($ip)) {
return redirect('/');
}
}
return $next($request);
}
protected function isValidIp($ip)
{
return in_array($ip, $this->ips);
}
protected function isValidIpRange($ip)
{
return IpUtils::checkIp($ip, $this->ipRanges);
}
}
.htaccess
code Source
here:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_URI} /thisdirectoryandallcontents
RewriteCond %{REMOTE_ADDR} !=111.111.111.111
RewriteRule ^.*$ /maintenance.php [R=302,L]
Nginx allow and deny IP
CloudFlare
How do I control IP access to my site?

You should use middleware for access control, the .htaccess 'can' technically be used for this, but it is highly recommended not to.
Rough example of possible logic to filter based on ip, that can be put in the handle function of newly created middleware:
if (!in_array($request->ip, ['127.0.0.1', '::1'])) {
abort(403);
}
return $next($request);

Related

HTTP 405 Method Not Allowed Lumen/Laravel

im trying to build an auth api for my react using lumen/laravel , each time i want to test it out with postman i get the following error HTTP 405 Method Not Allowed .
my routes :
$router->group(['prefix' => 'patient'], function () use ($router) {
$router->post('register',[PatientAuthController::class,'register'] );
$router->post('login', [PatientAuthController::class,'login'] );
});
CorsMiddlware :
class CorsMiddleWare
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
//Intercepts OPTIONS requests
if ($request->isMethod('OPTIONS')) {
$response = response('', 200);
} else {
// Pass the request to the next middleware
$response = $next($request);
}
// Adds headers to the response
$response->header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE');
$response->header('Access-Control-Allow-Headers', $request->header('Access-Control-Request-Headers'));
$response->header('Access-Control-Allow-Origin', '*');
$response->header('Access-Control-Expose-Headers', 'Location');
// Sends it
return $response;
}
PatientAuthController :
protected $patient;
protected $utilityService;
public function __construct()
{
$this->middleware("auth:patient",['except'=>['login','register']]);
$this->patient = new Patient;
$this->utilityService = new UtilityService;
}
public function register(PatientRegisterRequest $request)
{
$password_hash = $this->utilityService->hash_password($request->password);
$this->patient->createPatient($request,$password_hash);
$success_message = "registration completed successfully";
return $this->utilityService->is200Response($success_message);
}
/**
* Get a JWT via given credentials.
*
* #param Request $request
* #return Response
*/
public function login(LoginRequest $request)
{
$credentials = $request->only(['email', 'password']);
if (! $token = Auth::guard('patient')->attempt($credentials)) {
$responseMessage = "invalid username or password";
return $this->utilityService->is422Response($responseMessage);
}
return $this->respondWithToken($token);
}
.htaccess :
Options -MultiViews -Indexes
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
i have registred the middlware in app.php , but tho i still face this problem .

Laravel subdomain route matching issue

I need to implement subdomain for api routes, but I'm getting 404 error
I have APP_URL set to http://example.com
I've configured subdomain in RouteServiceProvider
protected function mapApiRoutes()
{
Route::domain('api.example.com')
->prefix('/api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
I see that problem is in Illuminate\Routing\Matching\HostValidator when it calls $request->getHost() it returns 'example.com', not 'api.example.com'. If i change APP_URL to http://api.example.com it works well.
class HostValidator implements ValidatorInterface
{
/**
* Validate a given rule against a route and request.
*
* #param \Illuminate\Routing\Route $route
* #param \Illuminate\Http\Request $request
* #return bool
*/
public function matches(Route $route, Request $request)
{
$hostRegex = $route->getCompiled()->getHostRegex();
$host = $request->getHost();
if (is_null($hostRegex)) {
return true;
}
return preg_match($hostRegex, $request->getHost());
}
}
Looks like i missed some configuration, but I haven't found any additional configuration requirements in laravel docs.
"laravel/framework": "^7.12"
ADDITIONAL: so currently i can see that laravel redirects api.example.com to example.com, so that's why I'm getting host validation error.
The next question is - Why it does redirect? =)
I don't think it will help somebody, but the answer was in one middleware which I've found in project. It was redirecting all invalid hosts (non APP_URL) to APP_URL:
if (auth()->user() == null && $request->getSchemeAndHttpHost() != $this->config->get('app.url')) {
$additional = '';
if ($request->input()) {
$additional .= '?' . http_build_query($request->input());
}
return redirect()->secure($this->config->get('app.url') . $request->getPathInfo() . $additional);
}
return $next($request);

How to ensure a new route hits correct middleware in laravel

I have a laravel 5.5 app I am working on and it has an existing route which serves up html ready to be rendered to pdf:
Route::get('wkhtml/read/{documentId}/{pageId?}', $namespace . 'WkhtmlController#getRead')
->name('wkhtml.read')
->middleware('wkhtml');
This all works fine and when you navigate to the page, it shows the page ready to be rendered.
I want to make a differentiation between the pages shown here and pages which are going to be downloaded, so I added this route:
Route::get('wkhtml/download/{documentId}/{pageId?}', $namespace . 'WkhtmlController#getDownload')
->name('wkhtml.download')
->middleware('wkhtml');
If I navigate to the url eg app.localhost/wkhtml/download/123, instead of showing the pages, the user is being redirected to the login page. Nothing else has changed, so it is a bit confusing.
The WKHTMLFilter looks like this:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Services\Document\Author;
use Illuminate\Http\Request;
class WKHTMLFilter
{
/**
* Handle an incoming request to one of the wkhtml routes
*
* #param Request $request
* #param Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// If it's coming from the wkhtml
if (!Author::isWkhtml($request)) {
return response()->make('Not wkhtml, not allowed here', 403);
}
return $next($request);
}
}
The app/Http/Kernel.php has this:
protected $routeMiddleware = [
...
'wkhtml' => \App\Http\Middleware\WKHTMLFilter::class,
];
The request doesn't appear to be hitting App\Services\Document\Author#isWkhtml, as I placed a die-dump there:
public static function isWkhtml(Request $request)
{
dd('here');
At the moment though, the request is not even hitting this filter.
How can I get the request to use the filter/middleware, if not like above?
Thanks in advance.
So it turns out in Laravel there are exposed routes in the AuthenticatedSession middleware, I just needed to add my new route:
protected $publicRoutes = [
'wkhtml.read', // existing route
'wkhtml.download', // new route
...
];

laravel 5.7, haproxy and ssl

my project works locally (dev) like a charm, but in production, where I did set inside the .env file APP_URL as https://myurl, generated links are in http, so I get the mixed content problem. How to force ssl? App is behind Haproxy, which terminates SSL connection, inside a LXC container. Here's my TrustedProxies middleware:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* #var array
*/
protected $proxies = [
'*'
];
/**
* The headers that should be used to detect proxies.
*
* #var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
any help?
Thanks
You can try this:
File: App/Providers/AppServiceProvider
public function boot()
{
\URL::forceSchema('https'); // Force HTTPS
}
Be sure on your .env files:
APP_URL = "https://"
Last step : File .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Get current route action name from middleware in laravel 5

I have a middleware like this:
<?php
namespace App\Http\Middleware;
use App\Contracts\PermissionsHandlerInterface;
use Closure;
class PermissionsHanlderMiddleware {
public $permissionsHandler;
function __construct(PermissionsHandlerInterface $permissionsHandler) {
$this -> permissionsHandler = $permissionsHandler;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
$routeAction = $request->route()->getActionName();
/*
do some operations
*/
return $next($request);
}
}
but $request->route() always returns null, I think its because the router hasn't been dispatched with the request.
Note: I added my middleware to Kernal.php global middlewares to run before each request as the following
protected $middleware = [
.
.
.
'App\Http\Middleware\PermissionsHanlderMiddleware',
];
I want to get route action name before the execution of $next($request) to do some permission operations. How can i do this ?
You cannot get the route action name if the router has not yet been dispatched. The router class has not yet done its stuff - so you cannot do $router->request() - it will just be null.
If it runs as routeMiddleware as $routeMiddleware - then you can just do $router->request()
You can get the URI string in the middleware before the router has run - and do some logic there if you like: $request->segments(). i.e. that way you can see if the URI segment matches a specific route and run some code.
Edit:
One way I can quickly think of is just wrap all your routes in a group like this:
$router->group(['middleware' => 'permissionsHandler'], function() use ($router) {
// Have every single route here
});
This is the solution I did in my project:
...
public function handle($request, Closure $next) {
DB::beginTransaction();
$nextRequest = $next($request); //The router will be dispatched here, but it will reach to controller's method sometimes, so that we have to use DB transaction.
$routeName = $request->route()->getRouteName();
if ($checkPassed) {
DB::commit();
return $nextRequest;
} else {
DB::rollback();
}
}
This is also fine.
$request->path(); // path
$request->route()->getName()//name of the route

Resources