Sessions with PHP and Amazon AWS EC2 - php

I am running a website on AWS with a domain name registered on Godaddy. The Godaddy domain mydomainname.com points to the IP of my AWS EC2 instance, which has public DNS ec2-x-xx-xxx-xxx.compute-1.amazonaws.com.
I am using PHP for the server side code and running into a problem with sessions. I set the $_SESSION variable when a user logs in, but the only problem is that if I log in at mydomainname.com the session is only set here and if I log in at ec2-x-xx-xxx-xxx.compute-1.amazonaws.com, the session is only set there. How can I get the sessions to coordinate across both of the sites, when they should be one-in-the-same?
I am a beginner at web dev, so please be kind :)

No one (other than you, and even then not for normal usage, just internal use and debugging) should be using ec2-x-xx-xxx-xxx.compute-1.amazonaws.com. Point mydomainname.com at it via DNS (using a CNAME, or Route53's ALIAS record) and have your users use the real domain name.

This won't work. Sessions require cookies on the clients browser which are sent with each request. This is the usual way that the server identifies which session relates to which incoming request.
The browser will only (almost only) send cookies back to the domain that issued them. This means that when the session sets a cookie from 'ec2-x-xx-xxx-xxx.compute-1.amazonaws.com', the browser will not send that cookie to 'my-domain.com' or any other domain.
There are a few exceptions and workarounds to this rule, Single Sign on being one example of transferring some state information between domain names.
If you are concerned about users accessing your website with multiple domains, then an solution is to configure the web server to redirect any requests for alternative hosts to the primary host name you wish to use on the server.

Related

Session not working in AWS server after setting domain name to ip address

This is the first time i am doing the deployment from my side and am new to AWS. I have a project deployed on Amazon AWS server for testing purpose. I have set the domain name as:
https://staging.xxxxx.com
I have a login page here where once the user logs in successfully i am setting the userId in the session and navigating the user to dashboard.
In the dashboard i have added a function to check whether session set with value of userId. If the session is not set then i am navigating user back to login page. This is to block the unauthorized access to site.
I am facing problem here. when i was working with the server before adding domain name to IP address wvwrything works fine. When i have added domain to the IP with https then the session is not working. What is the problem here with AWS? Am i missing anything.
In Amazon there is 2 IP for Typically EC2 instance. One is the internal IP that can change every time you shutdown or reset the system and the other one is public IP (that you have to attach yourself) when you want to do stuff inside that machine you can referred to localhost but you should never referred to the internal IP. When you do stuff that related to the outside world you should use public IP which is a static IP and will not change.

Unable to access files and website with IP address

I have my site hosted on GoDaddy and working on an application which is developed in Code-igniter Php. In my application I am using a library Grocery Crud. But when ever it access url related to the assets files and other files it calls them by IP address. As far as it was on local server it was running fine but as soon as I deployed it up it came up with the problem.
I know as the particular IP address is shared among many sites so that's why particular problem is occurring. but how to solve this problem is it what or something need to be configured in code igniter or some where else?
I understand that you are in a shared hosting environment:
I know as the particular IP address is shared among many sites
That's why you cannot access your site with its IP address. It's not possible. Period.
There's nothing to configure in Codeigniter, because it's the configuration of the HTTP server. HTTP server handles requests.
When you type a url in your browser, it will resolve the corresponding IP address. Then it will request the IP address, saying what hostname you are trying to reach. Based on these information, HTTP server will be able to handle your request and send it to the appropriate website.
When you type an IP address in your browser, HTTP server will not know what hostname you want to reach. Depending on the configuration, it will do what it has to, but probably not send the request to your site: in shared hosting environment, there is no reason for hoster to send request to a specific website it hosts. It will most probably display a 404, 403 or redirect to their homepage.
Many hosting providers assign a temporary hostname for your website, generally as a subdomain of theirs. You should temporarily use this hostname for your website.
To configure this hostname, open application/config/config.php and set the base_url parameter.
You can load different configuration files depending on your environment (for example: development, staging, production). See Handling multiple environments in CI documentation.

How to enable user custom domains in PHP

I'm having a system where users can input their purchased domain into their profile, so when accessing their domain, it should replace their custom domain, e.g.
http://domain.com/custom-name to http://purchaseddomain.com.
So when they access their purchase domain, it should take them to their profile including their navigation links, such as links on their page will be replaced with their purchased domain, for example viewing their records would be:
http://domain.com/custom-name/records to http://purchaseddomain.com/records.
Tumblr enables this feature, however I have no idea how this all works:
This is exactly how I like to have a feature like this, I've searched on SO, but it didn't seem to help.
Now this is a problem, I'm not sure how I can validate, confirm and merge their purchased domain into my server without a problem using PHP - I'm using Codeigniter for this.
Is there a solid, stable plugin/library or detailed tutorial that can have the ability to enable custom domains masking a internal domain?
My server is running Ubuntu 11.10 on nginx 1.0.6.
The templating will be just fine for me, which I can do - all I need help on is how to safely accept and merge their domain to my server.
EDIT: Just looked into nginx VirtualHostExample, this looks good overall but how will I be able to dynamically add/remove those domain entries while the domain has an A record pointing to my server?
You won't merge their domain to your server.
In fact, when they will register their domains, they will make it point to your server.
On your server configuration, you'll have to dynamically create rules that implicitly redirect the page to the one they created on your server.
So, users will see http://purchaseddomain.com/on-uri but you serve the page http://domain.com/custom-name/one-uri
I.E:
it's like if you added on an .htaccess - even if you don't use apache, it's just to explain what the "system" must be:
RewriteCond %{HTTP_HOST} purchaseddomain\.com$ [NC]
RewriteRule (.*) /custom-name/$1
The accepted answer mentions customers pointing their DNS to your web server. But, that's not enough to make it work in this day and age.
If your customers just CNAME to your domain or create the A record to your IP and you don't handle TLS termination for these custom domains, your app will not support HTTPS, and without it, your app won't work in modern browsers on these custom domains.
You need to set up a TLS termination reverse proxy in front of your webserver. This proxy can be run on a separate machine but you can run it on the same machine as the webserver.
CNAME vs A record
If your customers want to have your app on their subdomain, e.g. app.customer.com they can create a CNAME app.customer.com pointing to your proxy.
If they want to have your app on their root domain, e.g. customer.com then they'll have to create an A record on customer.com pointing to your proxy's IP. Make sure this IP doesn't change, ever!
How to handle TLS termination?
To make TLS termination work, you'll have to issue TLS certificates for these custom domains. You can use Let's Encrypt for that. Your proxy will see the Host header of the incoming request, e.g. app.customer1.com or customer2.com etc., and then it will decide which TLS certificate to use by checking the SNI.
The proxy can be set up to automatically issue and renew certificates for these custom domains. On the first request from a new custom domain, the proxy will see it doesn't have the appropriate certificate. It will ask Let's Encrypt for a new certificate. Let's Encrypt will first issue a challenge to see if you manage the domain, and since the customer already created a CNAME or A record pointing to your proxy, that tells Let's Encrypt you indeed manage the domain, and it will let you issue a certificate for it.
To issue and renew certificates automatically, I'd recommend using Caddyserver, greenlock.js, OpenResty (Nginx).
tl;dr on what happens here;
Caddyserver listens on 443 and 80, it receives requests, issues, and renews certificates automatically, proxies traffic to your backend.
How to handle it on my backend
Your proxy is terminating TLS and proxying requests to your backend. However, your backend doesn't know who is the original customer behind the request. This is why you need to tell your proxy to include additional headers in proxied requests to identify the customer. Just add X-Serve-For: app.customer.com or X-Serve-For: customer2.com or whatever the Host header is of the original request.
Now when you receive the proxied request on the backend, you can read this custom header and you know who is the customer behind the request. You can implement your logic based on that, show data belonging to this customer, etc.
More
Put a load balancer in front of your fleet of proxies for higher availability. You'll also have to use distributed storage for certificates and Let's Encrypt challenges. Use AWS ECS or EBS for automated recovery if something fails, otherwise, you may be waking up in the middle of the night restarting machines, or your proxy manually.
If you need more detail you can DM me on Twitter #dragocrnjac
This is what is working for me:
server {
server_name *.mydomain.com
root /var/www/$host;
...
}
Then you need to make directories like: /var/www/user1.mydomain.com/, /var/www/user2.mydomain.com/, ...
I couldn't figure out how to leave the '.mydomain.com' out of the directory name. If anyone has any idea, pls let me know :)

Transfer Session Data Between Apache Virtual Hosts

How do I pass PHP session data from one Apache virtual host to another? I am currently running Apache 2.2.17 and PHP 5.3.3 and I've set up one host to manage a single sign-on application and I need to pass this to two other virtual hosts that are running separate applications. This is something I intend to develop further, but for now passing session data would be the easiest.
Currently this code creates the first session in the SSO subdomain auth.domain.com and then passes the user back to the application interface app.domain.com (has been trimmed):
$user = new User;
$user->set_user_session();
Header("Location: $redirectURL");
exit;
The server is entirely managed privately so multi-user security isn't a worry. However, if anyone sees any security issues beyond that please let me know. If you know of a better methodology please share and I will research it further. I appreciate the help.
As far as I'm aware, PHP sessions are not (by default) virtual-host aware: you would need to pass the session ID as part of the redirect and then set it in the other virtual host. So something like:
$sessionid = session_id();
Header("Location: $redirectURL?session=$sessionid");
exit;
And then in the target of the redirect:
session_id($_GET['session']);
session_start();
Try that and let me know how it works.
Shared Sessions
If you are talking about subdomains (not specified) you may be able to set the cookie domain to just the domain so that the session ID is passed as a cookie between them
session_set_cookie_params(0, '', '.domain.com');
so, my.domain.com and your.domain.com both would get the cookie for .domain.com
With either option in place you could use a shared database or redis storage for shared session management. (share data between servers via Session storage)
As long the session storage configs are the same for all VMS.
Same Server
VMs on the same physical machine
session storage in files or memory will be shared via session IDs
MySQL Examples
https://github.com/sprain/PHP-MySQL-Session-Handler
https://github.com/dominicklee/PHP-MySQL-Sessions
Redis Examples
https://github.com/1ma/RedisSessionHandler
https://github.com/dostoevskylabs/slimphp-session-redis-middleware

Manage Cookie on Multiple "Domains"

We have a local web server in our office that we use for some reporting and mundane order processing -- nothing major. I recently added some quick code to add a cookie to certain workstations so the user doesn't have log in all the time. The problem I am running in to is that since the server itself acts as an additional workstation, people can access it from http://127.0.0.1, http://localhost or http://192.168.1.111. This ends up creating three distinct cookie domains. Is there any way to configure the server to force one or the other? Or is my only option to move all bookmarks to point to the actual IP address and warn people not to use 127.0.0.1/localhost?
The server is running Apache 2.2 on Windows.
You could check the $_SERVER['HTTP_HOST'] and redirect the browser if a visitor hasn't gone in via the correct hostname.
if('servername' != $_SERVER['HTTP_HOST']) {
Location('http://servername/');
}
If you're running an internal DNS server, you can configure a host/domain name for the server without having to register it - since it's for internal use only, you don't need to expose the name to the rest of the world.
Even without a DNS server, you can add an entry to each machine's hosts file to do the name->ip mapping.
Configure your site to use that name, tell everyone to use that instead, and then the cookies will take care of themselves, since they'll all be set using that host/domain name. You can then add vhosts for the IP-only hits and redirect them to the new named address.
Typically cookies are set to domain names, not ip address. When using a domain name you can use a wildcard setting
.apple.com
Then any variation of that domain will accept the cookies.

Categories