SSL Redirection in CakePHP - php

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.

Related

How can I make this RewriteRule redirect to the right page?

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).

How to call a function in class/function format from localhost

I am using Yii2 framework for my PHP development. In my view files, If I want to call any of the functions, I just use Class/Function name
Eg : www.example.com/SiteController[class name]/index[function name]
And it is calling the function.
I like to know, How to do the same in a pure php script ?.
I searched in many places and I could get the suggestions for special_autoload_register();. But I could not understand the exact practical application.
Guidance is expected and Thanks is advance.
Its easy :).
It's all based on apache module mod_rewrite. This module allows you to modify path behavior in .htaccess file.
Using this .htaccess file
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
you will get following behavior:
If requested file exists (/styles/style.css - styles, javascripts, images, etc) serve it (dont change anything on current behavior)
If requested file doesn't exist, go to index.php.
If you are redirected to index.php, you can find full requested url in $_SERVER['REDIRECT_URL'] or $_SERVER['REQUEST_URI']. There you can take it, parse and based on requested uri, behave.
Please take this as explanation post, not a guide on how to get this going. Mostly it requires some apache configuration because mod_rewrite is mostly disabled by default.
If you want to get things going, I would recommend this post.
To fully answer your question, you can for example explode request uri by "/" sign, save first part into $firstPart and second into $secondPart and then have
$controllerName = $firstPart."Controller";
$controller = new $controllerName;
$actionName = $secondPart."Action"
$response = $controller->$actionName();
So if you call /help/me, helpController->meAction() will be called.
I hope I helped :)
To do this, Yii 2 (and other PHP frameworks) have routers. The router in Yii 2 is the UrlManager class.
I would not advice you write a router from scratch for a solution you want to deploy. There are routing packages in PHP which you could easily use in your solution. I like Klein. It's a pure router in PHP.
However, if for academic purposes, you want to know how routing works in PHP, get to understand the $_SERVER reserved variable. It has all the details of the HTTP request coming to your script. You can then use the details from this to call the specific function you want to call.

Standard method for handling not found (404) errors in all kind of web server

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)

Disable direct access to files in PHP

I've already checked the issue disable access to included files , but I am wondering if that's the best solution.
Context: I'm building a bootstrap class for my PHP Framework, and realized that there are multiple solutions to this security issue.
After researching and reading posts like the one I mentioned at first and others related to htaccess, I think that there are basically three types of solutions:
1 - Checking a constant (like in the post I linked)
if(!defined('THIS_IS_NOT_A_DIRECT_ACCESS')) {
header('HTTP/1.1 404 Not Found');
include('./../error/404.php');
die;
}
Or
require('../error/include_file.php');
//
if(!defined('THIS_IS_NOT_A_DIRECT_ACCESS'))
{
header('HTTP/1.1 404 Not Found');
include('404.php');
die;
}
2 - Redirecting all calls to the Bootstrap and making a clever filtering.
//Something like
// if $urlRequested it's a file
// Go to Error
// else if $urlRequested it's not a controller
// Go to Error
// else
// Execute Controller Logic.
3 - Setting htaccess.
# Redirecting calls for non-directories, files or links
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA]
# Redirecting the rest of the calls to the error page.
RewriteRule ^(.+)$ index.php?url=error/404 [QSA]
Personally I think the solution 3 is the most interesting, but I am pretty new in the Htaccess control so I wonder if this is a safe solution.
For the purists and minimalists, the Question in here would be:
Are these (the three examples) nice direct access control systems for Apache-PHP applications? Else, which would be the safest approach? And the simplest?
This is a debatable topic but .htaccess rules applies to all the document on that particular directory. While applying 1 or 2 you may have to include that portion on every file.
Looking at all the options listed here IMO better would be to just place these files above the public_html folder or whatever is your DOCUMENT_ROOT folder and include with ../ paths. Then it would be available to your PHP scripts but for the web requests would get a default 404/ file not found error.

Slim Framework always return 404 Error

These days i'm using Slim Framework as my simplest tool to develop the php web api.
Using these two articles:
Coenraets
CodingThis
I follow some of the steps from there. Downloading the Slim Framework, putting the correct directory & files. Adjusting the initation statements such as;
//1. Require Slim
require('Slim/Slim.php');
//2. Instantiate Slim
$app = new Slim();
//3. Define routes
$app->get('/books', function ($id) {
//Show book with id = $id
});
And then, I modify the rest accordingly.
Such as my checklist that already done:
LoadModule rewrite_module modules/mod_rewrite.so -> enabled
Slim .htaccess:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule
^(.*)$ bootstrap.php [QSA,L]
httpd.conf: (Shared Link).
But, after Once I run this statement;
$app->run();
And I run it on my browser.... then, I got 404 Error while testing it on my Localhost. What's the solution for fixing that?
FYI, here is my simplest PHP file that i'm currently using it. (shared Link)
Problem is solved!
My apache is actually normal, and the .htaccess file provided earlier also normal.
The clue is the URL that I used.
Previously I used the invalid URL, thus it returned the 404 page error.
I just realized it when I Tried to access the newer GET URL via browser with this one;
http://localhost/dev/index.php/getUsers/user1
and now that works!
I just realized it once I found these statements;
If Slim does not find routes with URIs that match the HTTP request
URI, Slim will automatically return a 404 Not Found response.
If Slim finds routes with URIs that match the HTTP request URI but not
the HTTP request method, Slim will automatically return a 405 Method
Not Allowed response with an Allow: header whose value lists HTTP
methods that are acceptable for the requested resource.
I found this post while googling "slimframework 404". The post led me to a solution to my problem.
The Problem
I set up a site with the Slim framework using Composer and create an index.php with the following example code form slimframework.com:
<?php
$app = new \Slim\Slim();
$app->get('/hello/:name', function ($name) {
echo "Hello, $name";
});
$app->run();
Then I try to access the page using http://localhost/hello/bob. I get back a 404 Page Not Found page.
I was able to get to access the page using http://localhost/index.php/hello/bob.
The Solution
I found the solution by looking at /vendor/slim/.htaccess (included w/ Composer Slim install) and the URL Rewriting section of the Slim framework documentation.
I added a copy of the /vendor/slim/.htaccess file to the same folder as my index.php file. The contents of the file are:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
Now I can access the page using http://localhost/hello/bob.
You're right about to include the index.php on your file, but that happen because you're not working properly with your mod-rewrite
Please check the following link:
https://github.com/codeguy/Slim
In the Get Started part you could see how to configure your server (in case that you were using apache / lighttpd / ngynx)
I think your problem is at the "Resource parser" because you are no defining $id parameter at the request so, please, try this:
//1. Require Slim
require('Slim/Slim.php');
//2. Instantiate Slim
$app = new Slim();
//3. Define routes
$app->get('/books/:id/', function ($id) {
echo json_encode( getBook($id) );
});
// some stuff
$app->run();
Please, tell us if it's ok
For me the problem was that I'd forgotten to provide a .htaccess file in my document root.
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
If you're using Slim on Ubuntu 16.04 and you're getting the 404 error. Try this test from Tod Birdsall above:
If this works
http://localhost/index.php/hello/bob
and this doesnt work
http://localhost/hello/bob
and your .htaccess file in the same directory as your index.php and is configured as follows:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
And you still get the 404 error on Apache.
Try turning on Apache mod_rewrite as follows and restart Apache:
$sudo a2enmod rewrite
$sudo service apache2 restart
The Slim API should work correctly now as the provided .htaccess file will only work if mod_rewrite is enabled and that not the default on a clean install.
Here is how to turn off mod_rewirte if you need to.
$sudo a2dismod rewrite
$sudo service apache2 restart
Additionally mod_rewrite.so module must be loaded in httpd.conf or you will receive error 500.
LoadModule rewrite_module modules/mod_rewrite.so
For people who still search answers because previous doesn't work, this works for me :
RewriteBase /<base_of_your_project>/

Categories