I have the following problem. I'm developing a website using php and laravel 5.0.33. I have a development machine and a web server.
Now, I'm intercepting the register process by overriding the AuthenticatesAndRegistersUsers postRegister method, but with no luck because the interception is not performed on the server, on my local environment all works as expected.
I have also putted a die(); on the postRegister method of my AuthController, the one that overrides the defined on the mentioned trait and that line is never reached.
Original Trait method on \Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers :
public function postRegister(Request $request) {
$validator = $this->registrar->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$this->auth->login($this->registrar->create($request->all()));
return redirect($this->redirectPath());
}
My overrided method inside AuthController on \Project\Http\Controllers\Auth\AuthController :
use AuthenticatesAndRegistersUsers;
//Override of the register process
public function postRegister(\Illuminate\Http\Request $request) {
die ('aqui');
}
So, what is preventing the code from entering my overrode method?
In both, my local dev machine and the server, the php versions are the same.
Edit: Bad news the same behavior happens if I try to log in a user on the website, the login is not working as the register. The request never gets to the controller. This has cost me a whole day....:(. On the login I also overrode a method.
So, the error was due to a misconfiguration on the virtual host done by the hosting providers in which all requests urls get a trailing slash, but if a POST request is done and the trailing slash is added then the consequent redirection transforms the POST request into a GET one. After two days of explaining this to the hosting providers, I got the access to modify the virtual host configuration and I added a rule to avoid redirecting POST requests.
This was the redirection before the fix:
# Enforce trailing slash policy
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /es/$1/ [L,R=301]
And the redirection after the fix:
# Enforce trailing slash policy
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /es/$1/ [L,R=301]
Thanks to all for your interest and responses.
Related
First of all I hope I'll be clear enough and you can help me.
There's something I really don't understand, I've been trying to figure it out for hours, but in vain.
Here's the thing:
When I type domainname/profile, I want to be redirected to domainname/index.php?url=profile but instead, I'm redirected to domainname/index.php?url=index.php.
In my Rooter.php file, I did a var_dump($_GET) and it shows 'url' => 'index.php', that's how I know it.
Here's my Rooter.php:
<?php
require_once('views/View.php');
class Router {
private $_controller;
private $_view;
public function route() {
try {
// Load classes automatically
spl_autoload_register(function($class) {
require_once('models/'.$class.'.php');
});
$url = [];
if(isset($_GET['url']) && $_GET['url'] != '') {
$url = explode('/', filter_var($_GET['url'], FILTER_SANITIZE_URL));
$controllerName = ucfirst(strtolower($url[0]));
$controllerClass = "Controller".$controllerName;
$controllerFile = 'controllers/'.$controllerClass.'.php';
var_dump($_GET); die;
if(file_exists($controllerFile)) {
require_once($controllerFile);
$this->_controller = new $controllerClass($url);
} else {
throw new Exception('Page introuvable');
}
} else {
require_once('controllers/ControllerHome.php');
$this->_controller = new ControllerHome($url);
}
} catch(Exception $e) {
$errorMsg = $e->getMessage();
$this->_view = new View('Error');
$this->_view->generate(['errorMsg' => $errorMsg]);
}
}
}
?>
Here's my .htaccess:
RewriteEngine on
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^(.*)$ index.php?url=$1
The weird thing is, when I replace (.*) by [a-ZA-Z0-9]+, IT WORKS, I'm redirected to the page domainname/index.php?url=profile and my var_dump($_GET) shows 'url' => 'profile'.
What's wrong ? I wanted to use (.*) because it allows me to use severals slashes in my URLs, I can "fix" it by putting several RewriteRules for example RewriteRule ^[a-zA-Z0-9]+/[a-zA-Z0-9]+$ index.php?url=$1 but in my opinion it's a weird way to make it work, it's not fully dynamical...
Anyway I hope you will understand my issue. Thanks in advance!
Btw: I work in my localhost but I have the same issue on my distant server.
You have to understand that the rewriting engine makes multiple runs, so restarts the rewriting process if the request has been rewritten, unless you told it not to. That means you need to slightly change your setup to solve this:
RewriteEngine on
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteCond %{REQUEST_URI} !^/index.\.php$
RewriteRule ^/?(.*)$ /index.php?url=$1 [END]
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
I've noticed some people have had similar issues to this, but the issue has been to do with their vhosts and document roots, but most of the URLS on my site seem to be working fine.
For example, if I create the following routes
Route::get('cases', function(){
dd('here');
});
Route::get('bookings', function(){
dd('there');
});
my.local/bookings works absolutely fine, but my.local/cases just shows me the index of /cases page.
I have rolled back my code to a time it was definitely working, but its still returning the index of /cases page.
Why would laravel randomly stop some routes working?
Heres what i've looked at so far
Rolling my code back to a working state
Dumping composer autoload
Checking php artisan route:list to make sure it exists
Trying a server alias to see if a local IP would work instead
Changing my PHP version
It just wont show me this one page?
Any ideas?! Its driving me mad!
Note - /cases/create works fine, my index / page works fine, it just seems to be a GET request to /cases
The reason for this behavior is the default .htaccess rewrite rule:
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
The two conditions define that the request should only be forwarded to index.php (and therefore Laravel) if there isn't an actual file or folder matching the URL.
It seems like there is a cases folder inside public, so Laravel will not handle requests to that folder.
You can either rename the public/cases folder / the route or remove the first RewriteCond condition. But removing it might have unintended side-effects.
It's so strange that the POST API routes doesn't work!
Check this simple POST route in api.php:
// This route doesn't work!
Route::post('/test', function (Request $request) {
return 'test';
});
It gives me this error: Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException!
But if I change the request verb to GET, then both GET and POST work just fine!!! It's making me crazy!
// This route works on both, GET and POST!
Route::get('/test', function (Request $request) {
return 'test';
});
And yes, as you know the API routes simply don't use the VerifyCsrfToken middleware. So the middleware is not the issue obviously! And php artisan cache:clear is not also the answer :(
Did anybody had the same problem? Any help would be so appreciated.
Oh yea! As #patricus also mentioned in comments, I was experimenting a stupid redirect without knowing it! Let me clear this for anyone else who is experienicng the same thing and don't know where this issue is coming from!
You need to make sure the URL that you're connecting to is not going to be redirected behind the scenes whatsoever...
e.g. in my own hosting panel, I have set to add WWW in all of my URLs... So when I was trying to access the https://example.com/app/public/api/test URL by POST method, I was getting the MethodNotAllowedHttpException error! Because my URL was redirecting to https://www.example.com/app/public/api/test and in redirection it will change to GET! And as I didn't set any GET routes... So obviously I was getting the MethodNotAllowedHttpException exception :)
That's stupid, right? Yea, I know! Also make sure if your app is on a SSL domain, always connect to https:// instead of http://. Because it is not only secure but also a redirection may happen again, without you knowing it! How? By your own .htaccess file that you have changed or your hosting support has changed it for you and you don't remember (check this answer as well):
# Let's force using SSL on all of our URLs and also forbid non-secure POSTs
RewriteEngine On
# Forbid non-secure POSTs
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_METHOD} =POST
RewriteRule ^ / [F,L]
# Force SSL
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Or by services such as CloudFlare, which help you be more secure and redirects all of your URLs from http:// to https:// if you have set this setting in your CloudFlare panel and again you don't remember that!
I use Apache as default web server in my projects and usually use mod_rewrite rules with .htaccess file in order to navigate virtual urls like: http://example.com/en/page/parameters... to index.php file and everything works fine.
But i'm trying to improve my projects compatibility in order to work with every web servers such as Nginx, Litespeed, lighttpd, IIS and so on. but obviously .htaccess file is not supporting by all of them. I'm looking for a standard method or a permanent solution to handle not founded errors by running a php file instead to simulate mod_write someway.
if such standard method doesn't exist, what is best substituent way to handle rewrite rules like beyond codes for most common web servers such as above examples:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Options -Indexes
That Task would require you to follow certain design principles.
First of all you would need to have some kind of Front-Controller which handles all incoming requests (to prettify URI's you'd still need to set up some kind of URL-Rewriting which is again webserver dependent).
Next you would need some kind of routing layer which dispatches a URI to a certain action. Everything that is not supposed to be dispatched by your router should throw a 404.
That's about it. Here is a very basic example which outlines the parts that have to be done. But be careful: In real world applications both, the Front-Controller, and the Router are some of the most important parts of an application, so consider to not reinvent the wheel.
<?php
$routes = [
'home' => 'home.php',
'about-us' => 'aboutus.php'
];
if( ! array_key_exists( $_GET['page'], $routes ) )
{
// The 'page' get parameter has no value that matches with the
// router so respond with a 404
header('HTTP/1.0 404 Not Found');
echo "I'm a 404 and I'm handled via PHP";
}
else
{
echo $routes[ $_GET['page'] ];
}
(URL Rewriting not included since it's not part of the question)
how can we redirect "http://www.example.com" to "https://www.example.com" when any user types "http://www.example.com" in cakePHP ?
You can use a .htacces file to do it before loading any php. Then the servers doesn't need to load the PHP scripts
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
While the currently accepted answer focuses on the use of apache's rewrite module, there are a number of cases where this answer doesn't apply, for an obvious example when apache isn't used at all or when rewrite module isn't and can't be enabled.
So a more generic answer would involve you adding this to your AppController
public function beforeFilter(Event $event) {
if (!env('HTTPS')) {
return $this->redirect('https://' . $this->request->host() . $this->request->here(), 301);
}
}
Which would make a permanent redirect to the same url under https if https isn't used.
You don't specify cake's version so the above is cakephp 3 code, just remove Event $event from the function arguments to make it cake 2.