I have some trouble with setting up a correct Cookie path. What do i want to achieve?
I have a project that runs on my localhost server, with a path http://localhost/project_folder/Controller/function
I can set the Cookie path using the mentioned relative path /project_folder/Controller/function and it works
But when the project runs on another server, where the structure is a bit different, i.e.: http://localhost/project part is replaced by http://www.example.com/Controller, then the trouble begins
I am using CodeIgniter framework.
To achieve the metioned i have tried using the base_url() function CodeIgniter provides and if i change the site path in the configuration it works on the second server but does not work on the local one and vice-versa ...
How should i properly handle the Cookie path in this situation?
EDITED:
It's a simple Cookie set (i'm using a Custom cookie function in JavaScript and i'm setting the Cookie via JavaScript):
createCookie('filter_products', params, '1', '<?php echo base_url('Controller/function'); ?>');
The problem is, that the base_url() function returns the path below like i said before:
http://localhost/project_folder/Controller/function
But on the server the localhost/project_folder/ part is replaced by the domain name, so how can i create the Cookie path dynamically?
The first thing that comes to my mind is, that you should avoid setting Cookies via JavaScript if it is possible and use the CodeIgniter built-in helper or the native PHP functions.
To your question:
For dynamic decision on which server you are, you can use the PHP super-global $_SERVER value which is accessible from anywhere in your code. The SERVER_NAME field contains the actual name of the host, so you can use something like:
<?php
if (isset($_SERVER, $_SERVER['SERVER_NAME'])) {
if ($_SERVER['SERVER_NAME'] === 'localhost') {
// set base path to localhost/project_folder
} else {
// set base path to www.example.com <- MORE SECURE
// or, set base path to $_SERVER['SERVER_NAME'] <- INSECURE (any server could be written to the config)
}
}
Related
I have a webservice which requires a login from the user and i create the standard
$_SESSION['XXX'] variables for the user.
I wanted to create a "demo" of my application so i created another folder for it.
Same code in there and everything except the database.
Problem is that when the user logs in one of those two it can access both.
So if he logs in in the demo application which will set a session variable with that
same thing he'll be able to access the "normal" application.
How can i separate those two loggins?
Should i change my session variable for the demo or is there another way to solve it
according to the folder the files are in?
Thanks
I faced the same problem. And i also solved it. For example if you are taking 2 variables which are Name and ID from both site, you just change the variable name like below:
For Site1:
$_SESSION['username_site1'] = $username;
$_SESSION['id_site1'] = $id;
And for site2:
$_SESSION['username_site2'] = $username;
$_SESSION['id_site2'] = $id;
In this way two site will have two different session names and will never let you get into each other.
Let me know if it worked for you also.
regards.
Use different paths for the session cookie in the 2 applications.
Obviously you can't have the 2 settings in one php.ini file hence:
set the php_admin_value in a locationMatch directive in the httpd.conf (apache)
set the php_admin value in a .htaccess file
add a prepend to the PHP scripts (or amend a common include file) to set the path.
Note that if you're specifying the path in code, then session_set_cookie_params() is recommnded over ini_set(). Assuming the default config in php.ini is for the demo site (which should be using something like '/demo/' NOT '/')...
if (false===strpos($_SERVER['REQUEST_URI'], 'demo') {
// using live application
session_set_cookie_params (1200, '/live/');
}
(the above must be run before calling session_start())
You can change the path to which the session data is saved...
N.B. Ensure the folder exists and is writable by the webserver user (e.g. nobody)
<?php
$newPath = '/tmp/sessions/demo';
ini_set('session.save_path',$newPath);
?>
I once used CakePhp, and when I push my code from local to server,
I have to change something like a href="http://localhost/" on the local environment to http://domain.com/ everytime I push the code to server,
Later I know I can use to avoid that.
But I have try that again, this time I do NOT use CakePhp, However I want to do something like did, can somebody show me how to do it?
You can either :
use config files and check their contents to create your links.
check the domain name when creating your links.
use relative links (./ , / or folder/).
define a host variable manually (not very clean, but probably the quickest way eg:
<?php
define(HOST, 'http://localhost'); //change that to http://domain.com when you upload your code)
?>
and build the links like that :
<img src="<?=HOST?>/img/random_image.jpg"/>
Just use
href="/"
instead of
href="http://localhost/"
if you are using HTML helper.
Doing $this->Html->link() will keep you away from the trouble.
I have looked all over the place, but still cant figure out how to set a global variable in PHP (Lithium framework).
My goal is to make the server root always accessible everywhere, without having to write this code everytime, to make my app independent of the hostname it is running on :
<?php echo "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>
Please don't tell me to just use absolute or relative paths, as I have tried everything that way, and it is simply too messy (besides not working most of the time).
It looks like your code above is in a template. So you can use $this->request()->to('url') to get the current url. Or from a controller, it would be $this->request->to('url'). You can also pass 'absolute' => true to the options for Router::match. Unfortunately, the html link helper - i.e. $this->html->link(...) - doesn't pass the 'absolute' => true option through to the Router::match but you can call $this->url() which is passed through to Router::match. So it would be $this->url('/relative/url', array('absolute' => true)).
See the docs for Router::match
The Request object also provides access to things like http host and request uri. See the docs for Request::env()
But, to your original point about global vars, I think the Environment class should be used for this. You can put arbitrary data in it -- and even set it in your bootstrap to have different values for different environments (i.e. dev vs. staging vs. production).
Sorry, but use relative paths and use the link generator helper, which won't get what you're trying to do wrong.
See the docs.
I have an external javascript file that uses the getScript() function to run another JS file.
I have those all on static.mydomain.com. (I'm new to setting up CDNs)
getScript() doesn't seem to allow cross-domain requests because my HTML is on domain.com. But then I tried using relative paths according to this post: Dynamic URLs in CSS/JS
It works for CSS but does not work for JS (specifically within the getScript() function). What's going on here? What are some ways to mitigate this problem when dealing with CDNs?
The getScript method actually makes an ajax call, hence the reason it's not working. Unless you need access to things like 'was the script successfully found' and the like, it's better to just write up a quick method like...
function addScript(source, domain) {
$("head").append("<script src='"+ (domain ? domain + source : source) +"'></script>");
}
That will just add scripts to the head of the page, and let you add an optional domain to point to in case you want to change it up.
How can I get real host name by not using $_SERVER['SERVER_NAME'] in PHP? Is there other more reliable way to get it ?
I have created a function which gets host name from the path to the domain.
I would like to avoid using $_SERVER['SERVER_NAME'] variable, because it can be faked by sending modified headers in the HTTP request.
This is my current implementation (this works if the path has an actual domain name in it. For instance: /vhosts/website.com/public_html):
function getServerName() {
$path = realpath(__FILE__);
$url = array();
preg_match_all("/\/[a-z0-9-]+(\.[a-z0-9-]+)+/i", $path, $url);
// 4 is minimum requirement for the address (e.g: http://www.in.tv)
if (strlen($url[0][0]) > 4) {
$result = str_replace("/", "", $url[0][0]);
return $result;
}
else
return false;
}
Thanks!
If you want a server name that can't be set by the client, use $_SERVER['SERVER_NAME']. It is set by the server itself but can also be forged under certain circumstances using a bug, as Gumbo points out and links to in the comments.
I think the one you are referring to is
$_SERVER['HTTP_HOST'];
which, given the HTTP prefix means it comes from the HTTP Headers.
You might want to use:
$_SERVER['SERVER_NAME']
which is defined by the server and can't be changed via a request?
this will get the hostname server-side, but if you're running on a commercial host (not hosting yourself), I don't imagine this will be all that useful.
$host = php_uname( 'n' );
If you're using Apache, what you should do is make your server / site only answer to certain names (else there should be a default that doesn't do much). You can do with with the ServerName and ServerAlias directives.
Edit: as pointed by Gumbo, the original poster probably means HTTP_HOST rather than HOST_NAME. Otherwise, my answer is plain wrong.
The HTTP_HOST variable reflects the domain name that the visitor used to access the site. If doesn't have anything to do with file paths! Its value is conveniently stored in $_SERVER['HTTP_HOST']. Is there any other way to get it? Of course, there're normally several ways to do things. For instance, this works when PHP runs as Apache module.
<?php
$request_headers = apache_request_headers();
echo $request_headers['Host'];
?>
The question is: why would anyone want to do such a thing? Why replace a reliable standard method with a quirky workaround that eventually fetches the same piece of data from the same place?
You have the concern that $_SERVER['HTTP_HOST'] is altered by the HTTP request. Of course it is: that's where it comes from. The browser has to specify what site it wants to visit (that's the base of name based virtual hosts) and if it sends a rogue value, well, it just won't reach the site.
Of course $_SERVER['HTTP_HOST'] can be modified by the client - because in fact IT IS sent by the client. This is part of the http protocol. If you want to get the primary server name defined in the vhost configuration of apache or whatever you can access $_SERVER['SERVER_NAME'] as proposed by the others.
I suggest it is not wise to extract the domain name from the file path of the server (which is stored in __FILE__) as it may render your application non-relocatable (it will no longer be storage location agnostic).
You may see the contents of the array by dumping it within the script using var_dump($_SERVER) but keep in mind the not all web servers and all web server settings expose the same environment. This is documented in the web server documentation and I think it is partly documented in the php online docs.
Update / Important notice: As others pointed out, the content of $_SERVER['SERVER_NAME'] could be spoofed if apache is configured for UseCanonicalName off (which may be a default setting if you are using eg Plesk-based hosting). So actually going with the __FILE__ can solve this (if your doc root contains the host name). The bigger problem of the first approach is that it can be used to inject any sort of stuff into your application (SQL, JavaScript) because php programmers usually take it granted that SERVER_NAME is no user input and thus apply no sanitizing to it.
You don't. That's the purpose of the $_SERVER variables. If you want to get the HOST_NAME from the path, you must first get the PATH from $_SERVER['HTTP_HOST']