Client Side Data saving with PHP/Javascript - php

I want to make a website that would be like craiglist.org. If you go the site and click on any of the city it will redirects you to the city subdomain. And after that anytime you go to the craiglist.org it will redirect you to the city subdomain. So I need to keep the city/country name to my client's machine.
At first I thought I can do it by Cookie with setting expire time. I tried that but the expire time is not working as when i close the browser that means when session ends it is not getting the cookie anymore.
But if it was ok with cookie then also it may not be ok for the destination as if I browse the site from Mozilla and closed and open the site with IE it should redirects me to the visited site that is not possible with cookie i think?
Can you please give me some suggestion ? How can I do the thing. I am going to do the application with Codeigniter/Php.
Thanks
Sumon

cookie is the right approach.
you cant achieve something cross-browser ... well you could use flash cookies or re detect the ip adress etc but thats stupid...
well craiglist.org seems to redirect me according to where my ip adress comes from.
to do this you should check out this site: http://www.maxmind.com/app/geolitecity
generally speaking you should always give the user the possibility to switch by hand.
from a usability optimizing point of view i would suggest the following scenario:
user hits welcome page
welcome page detects city of the user using geoip
3.1 if city has been detected successfully user gets bounced directly to the subsite, cookie is saved
3.2 if city is not successfully detected, welcome page shows a selection list. once the user clicks a selection list the cookie is set and the user gets the specified subsite
on every subsite there is a well visible button on the top "switch city" or something.
if the user clicks it he gets to the welcome page, but with a parameter "userelection=true" ro something, so that the automatic ip detection and redirection doesng kick in.
the user selects the desired subsite, gets a cookie and gets redirected.
5.
if the user hits the welcome page again and a cookie is found he is redirected to the subsite, cookie can be overriden, thats no problem...
the easiest and bset solution would be setting the cookie using php and then do a header redirect!
this way you eliminate javascript, which can be turned off or something.
just use this php command:
setcookie("city", $value, time()+(86400*365));
or something similar. heres the manpage:
http://php.net/manual/en/function.setcookie.php
you can check for cookie values using
if($_COOKIE['city'] != '')
edit:
well as of the confusion i have an working example for you here now, just paste it into a php file and save it to your webserver :) the check for subsite won't be necessary as you said you are redirecting to external sites (subdomains) anways.
keep in mind that you cannot access a cookie from a subdomain if you set it on another subdomain! maby this was your problem, therefore the checking and redirecting int he bootstrap file.
well here you go. any questions? comment!
<?
/* this is if we are at a subsite. you wont need that as it will be external subdomains anway just for the purpose of a working example here.*/
if($_GET['subsite']!="") {
/* the change link has the paramenter userselection which overrides any autoamtic detection by cookie or ip or whatever, this is important if the user wants to change or the automatic change fails or is wrong*/
?>
you are now at the subsite of <?=$_GET['subsite'];?><br/>
click here to change
<?
}
else {
/* only try to automatically redirect if we have either cookie or user specified data, but dont if the flag userselectino is true. because the user wants to change.
you could ip-detect the city at this point.
*/
if(($_GET['go']!=''||$_COOKIE['city']!='')&&$_GET['userselection']!='true') {
/* if we had ip detection the priority of it would probably go here */
$target=$_COOKIE['city'];
/* the get varaible overrides the cookie value as its user supplied and more important*/
if($_GET['go']!='') {
$target=$_GET['go'];
}
/* set the cookie, don't care if it already has been set*/
setcookie('city',$target,time()+(86400*365));
/* redirect the user */
header('Location: ?subsite='.$target);
}
else {
/* well we either have neither cookie nor user specified city or the user wanted to change teh city, lets display the selection dialog!*/
?>
hello! select your city:<br/>
vienna
new york
<?
}
}
?>

The cookie is the best way to do this; if the web browser's cookie is not being reloaded after closing the browser, you must have something wrong when creating the cookie.
Have a look at the PHP docs for setcookie(): http://us3.php.net/set_cookie, make sure you are providing an expire time far in advance, such as strtotime("+300 days"). On the server, to read the cookie back, simply use the $_COOKIE super global. Link: http://us3.php.net/manual/en/reserved.variables.cookies.php
Also, be sure to check your browser settings for the handling of cookies... maybe it is set to delete cookies after closing the browser.
Finally, you could also use the user's IP address -- but be warned that users can share the same IP address if they are on the same local area network, such as a university or corporation. You could even auto-choose the location by using an IP location lookup service such as http://ipinfodb.com/
You can inspect your website's cookies in Firefox by going to
Tools -> Page Info -> Security -> View Cookies

It seems illogical to try to save browser state across browsers. If a user switch browser, they are usually not guaranteed to have the same browser settings, unless they have an account on that site.
If they are registrered users, you should store whatever state you need in your database, and retrieve it on login. Then you can always cache the data in a client-side cookie, so you don't need to fetch it everytime.
In my opinion, storing browser events across different browsers for anonymous users would not be worth the efford.

Related

SameSite=Lax blocks cookies from the same domain, sayng it's different domain

I'm having a page, that redirects to an external URL, where a customer is adding their data and then is returned back to my site. However when the customer is returned the session cookie is blocked by the browser, because "the request comes from a different site". This happens in FireFox (with SameSite=Lax) 100% of the times and "whenever it wants" in Chrome. I don't understand why does this happen, how does it see the site is different and what really the site is (there is no info in the Dev tools).
This blocking logouts the customer and I need them to be logged in.
Any help will be appreciated!
I did a workaround. I'm posting it here in case somebody has the same issue and the fix will work for them. When the user is redirected to the other side I'm sending a session id in the return URL. The if the user is returned and is not logged in I add the cookie with that id and refresh the page, this way the user is returned logged in.
I think what you want is: when user came back to your site, he no longer needs to login. So in your back-end, just set the cookie's flag to Samesite = None; Secure. This will make the browser to send cookies regardless of where he came from ( the external domain ).

Cross Domain Sign In

I have a few domains all on the same server, with the same IP and the same databases - that can be accessed by all 5 of the domains.
I have recently remade my login system, so that on my main domain, the cookie works for not only the main domain but the sub domains as well. What this means is that if a user logs into one area, they are signed in everywhere. Which is great! I write a cookie with their hash (taken from the DB) and check for that when loading each page, and they are automatically securely signed in.
This is lovely, but the problem then comes when switching domains, as cookies seem to be locked down to domains. So my other domain (lets call it domain2.com) cannot read the cookie from domain1.com.
Are there any clever ways around this? I could write something to the database, such as IP, but that wouldnt be very secure as the company i work for everyone is on the same IP and therefore it wouldnt be specific.
Or I thought about maybe including a hidden iframe on the page, which actually links to a page on the main server, and pulls the information that way somehow.
I am not sure, but I am sure it can be done. Any ideas?
Browsers, for good reasons, do not allow cookies to be read from any other domain.
What you can do is have domain2.com redirect to a page on domain1.com which checks if the user is logged in and if they are it redirects back to domain2.com with the user's id which can then log them in.
You should not depending on original PHP session functions Collections.
Here is what I have done :
After login success , Server side should return a "session ID" to the browser and store by JavaScript or some how, mean while the "session ID" should be store in database as a successful signal and you do a login time next to the session ID if you needed.
Now you can share the session ID in any IP server you want and make your client connect to(some trick like you redirect to the new domain and post the SID) then establish a PHP session.

access php cookie from same domain not working correctly

I'm not great at PHP, and everything I currently know, I have just taught myself by browsing the internet.
I am currently trying to work with cookies in my page, in order to set up a persistent log in for a day.
Basically I have gotten as far as managing to set a cookie, with a value of the session username. This value is set when the user logs on.
So the user enters credentials, php checks against mysql database, if it is successful then the username is set as session variable, and this is then set as a cookie.
This works, as if I run this php and immediately echo the cookie, the username is displayed.
This is all done on my login form which is brought up in a tinybox (similar to a lightbox and other such pop up windows). The cookie and echo seems to work correctly from here.
However, when the login is successful, it refreshes the parent page, (root page of my site) and all seems well. However, if I then try to echo the cookie from the index page, I can not access it.
I know cookies have limitations on them for security, but seeing as how my login page, and my home page are on the same domain, then I thought this would have worked.
Is this something I am likely doing wrong, or is it a cookie limitation. Would it work if I set the cookie from the index page itself, rather than from within a tinybox?
If anyone wants examples of the code I am using, it can be provided.
Many thanks
Eds
Which navigator you use? Chrome can't work by default with local cookies. You can enable with command line --enable-file-cookies
http://code.google.com/p/chromium/issues/detail?id=3014
Was helped out by DaveRandom on this one.
Turns out I had to add "/" as the root path for the cookie, so that it was available to parent pages.

How Does Website Access Control Actually Work?

I am just starting to learn about web development and something has been niggling me for a while now, How a website controls what you can access and cannot access.
For example, a website like Facebook. When i first go to the site, it presents a login form, once i am logged the same page that i tried to access before now shows information relevant to me that i could only access once logged in, i can navigate to a different site and then comeback to google and it still allows me to use if without logging on again.
How exactly would a site block someone trying to access a particular page when they are not logged in, lets say the page viewProfile.php. How does the website know who to allow access to this page?
I realise this question may seem confusing and elementary but its just a something that came to me whilst viewing facebook.
Thanks.
This is a very simple concept called sessions.
When you visit facebook, it reads unique information sent to it via the connection such as IP address, browser, and some other minor information, when this information is combined it creates a unique identifier.
this unique identifier is then stored in a file like so:
d131dd02c5e6eec4693d9a0698aff95c.session
So when you login with your credentials there application add's information into this file such as last activity etc.
When you go away and come back, facebook will then read the information that's sent with every requests, it then add's it all together and creates a unique hash, if this hash exists within it's storage system it will open it up and read the contents, and know exactly who you are.
all this is combined with cookies, the unique hash is sent back to the browser and stored in your cookies folder, this cookie file is sent back to facebook with every request.
PHP Handles this for you internally so it's pretty basic to get it up and running: http://php.net/manual/en/features.sessions.php
Here's an example that may help you understand the concept a little more.
<?php
/*
* The session_start generates that hash and send a cookie to the browser
* This has to be first as you can only send cookie information before any content
*/
session_start();
/*
* Anything storeg within $_SESSION is what's been read from the session file and
* We check to see if the information has already been set on the first time the user
* visited the site
*/
if(!isset($_SESSION['hits']))
{
$_SESSION['hits'] = 0;
}
/*
* Now we increment the value every time the page is laoded
*/
$_SESSION['hits']++;
/*
* now we display the amount's of hits the user has loaded the page.
*/
echo 'You have vistited this site <strong>' . $_SESSION['hits'] . '</strong> times.';
?>
if you load this page and then hit F5, the session value get's incremented every request so you should see something like:
You have vistited this site 1 times.
You have vistited this site 2 times.
You have vistited this site 3 times.
You have vistited this site 4 times.
...
The session file is unique to each person visiting, thus meaning that when using the session variable in PHP it would be to that user only, so everyone get's there own individual session.
as your researching it's goods to search StackOverflow for certain tags, such as PHP and sessions.
https://stackoverflow.com/questions/tagged/php+session
Here's a good question in regards to cookies and sessions advantages etc.
Purpose Of PHP Sessions and Cookies and Their Differences
A website uses something called a "cookie" to store information on your computer.
This information can hold any text string, but in this case it is probably a unique ID that Facebook knows (probably stored in a database somewhere) is tied to a certain user. Cookies can only be read by the website that sent them and by the browser itself.
The login page sends a POST/GET request to a script that generally checks the username/password combo against data in a database a database. If the data is found to be valid, then the user is granted access to the websites landing page (the page after login) and a cookie is stored. If it is not, they are sent back with a error message.
Cookies can also have a "lifespan". This lifespan can be anything: for a certain amount of seconds; until you leave the site; until you close your browser; or forever (there are probably more.)
The website that sent a cookie can also delete a cookie before it expires. This is how most "logout" buttons work.
To allow only logged in users to view content you can first check for a sign that they are logged in, such as look for an active session and that it has a flag which tells you they're logged in ( which you control ). In PHP at the top of a page you can simply:
<?php session_start();
if(!isset($_SESSION['loggedin'])){
header('Location: http://example.com/login.php');
}
?>
which will redirect non logged in users to a login page. Upon success login, you should set $_SESSION['loggedin'] to a value.
To check whether a person who is logged in is allowed view a particular profile is down to looking up where the page is restricted to friends only, and if so, checking that the loggedin user's id is in the profile owner's friend field in the DB.
It is done with cookies. When you log in, the site puts a cookie into your browser for a set amount of time (generally a very long time so that you can stayed logged in). When you access the site again, your browser sends the cookie back to the site (and the site sets a fresh cookie). In any browser, you can find the list of cookies somewhere in the options.
If you want to know more about cookies, you can read the wikipedia: http://en.wikipedia.org/wiki/HTTP_cookie
Do a Google search for "Session Management."
Summary
when you login to a site you get a unique id. That id pulls your data from the database and then populates a dynamic page, like viewProfile.php with your data. So each user pulls the same file, viewProfile.php, but gets different results based on their unique id.

Cross domains sessions - shared shopping cart cross domains

we are solving the problem with eshop (php, mysql). The client want to have the same eshop on two domains with shared shopping cart. In the shop customer can do the shopping without users account (can't be logged in). And there is the problem, how to make the shared shopping cart cross domain.
The data from cart is stored in sessions, which we stored in database too. But we can't solve the problem in carrying data over domains. Identifying unlogged user is not holeproof (research).
The example, how it should work
Customer goes to domainOne and add some things to the cart. Than he goes to domainTwo (by link, typing domain address, however) and add some other things to the cart. In the cart he has things from both domains (after refreshing page).
Do you have any idea, how to solve this problem?
What didn't work:
redirecting is not possible due to customer requirments
cookies are related to domain
set_cookie with the other domain didn't work
the simpliest way is to carry over only the sessionid (stored in cookies) but we don't know, how to wholeproof identify unlogged users.
is there any other place, where data can be stored on client side except cookies? (probably not)
we can't use sending sessionid by params in url (if user click to link to the other domain) or resolving the header referer, bcs we don't know, how user can achieve the other domain.
If you can't understand me, take me a question. If you think, that having eshop on two domains with shared (common) cart is bad idea, don't tell me, we know it.
Thanks for each answer.
You can use a third domain to identify your customers over all domains.
Use for example a PHP File on http://thirdDomain.com/session.php that is included on all pages on both shops.
Sample:
<script type="text/javascript" src="http://thirdDomain.com/session.php"></script>
After your customer switches domains, you can identify him as the same customer using the third domain.
You can assign the session id on both shops to the session id on the third domain to access the cart on both shops. You only need to inform the third domain about your shop sessions (i.e. add them as parameter).
Depending on how flexible you are with your code and templates, you can even use an output from the third domain to define the session id in your shops. This way you can use the same session id on all domains.
But normally a session id assignment should be the more secure way.
Using the javascript version you can also output scripts that may add a session id to all outgoing links and forms to the other domain in the current html page. This might be interesting if you can identify your customer as having cookies blocked.
You can also use the javascript to inform the parent document about an existing session.
This keeps getting asked.
Have a search for SSO.
You need to pass the session id in the URL (or vai a POST) across the domains, then:
1) check the session does not already exist on the target domain
2) rebind the session using the session id sent
e.g.
if ((!$_COOKIE[session_name()]) && $_GET['passed_id']) {
if (check_session_exists($_GET['passed_id'])) {
session_id($_GET['passed_id']);
}
}
session_start();
...
function check_session_exists($id)
{
$path=session_save_path() . $id;
if (file_exists($path) && (time()-filemtime($path)<session_cache_expire())) {
return true;
}
return false;
}
This also means you need to add '?passed_id=' . urlencode(session_id()) to any URL pointing to the other domain.
C.
The schema is quite simple and widely used. By google for it's numerous services for example. You have a whole picture by tracking down HTTP interchange between your browser and various google services to get the idea.
Suppose we have our client authorized for the 1st domain. By getting to the second, we have to:
start a session and store some token in it.
ask browser to request 1st domain somehow and send this token along.
1st domain will recognize our client and make a connection in the shared database between this token and user id.
By requesting second domain again, we will have it authorized for it's already started session.
The only question remains is how to request 1st domain. It can be a picture, or JS request or entire page redirect. Certain choice is up to you.
You can use Flash LSO's for this matter i think. Normally LSO's are stored in their domain specific sandboxes, but if two domain objects allow, they can communicate as stated in the "cross-movie communication" section in http://download.macromedia.com/pub/flash/whitepapers/security.pdf.
For general info about LSO's:
http://www.adobe.com/products/flashplayer/articles/lso/
SSO.
CartA has iframe that 1) checks if the user is "active" (has session) 2) creates anon session
CartB has iframe that do 1) or 2)
iframe loads from SSO domain (any domain you can have)
SSO solution: build yours or use others - like simplesamlphp or something...
And there should be no need to pass sessions/params with URIs...
You can store data in other places than cookies (e.g. Flash cookies, localStorage) but all use same origin policy, which is the standard security model of the web: data stored by a domain can only be accessed by that domain and its subdomains. The standard workaround is to embed an iframe from the foreign domain into the page. That iframe will have access to the cookies of the foreign domain, and its url will be controlled by the local domain, which allows for communication.
A simple solution based on that is to have a table of (domainA sessionid, domainB sessionid) pairs. When a new user arrives to domainA, (new sessionid, NULL) is added to the table; the page shown to him includes an invisible iframe with source = http://domainB/mergeSessions.php?sessionA=1234. mergeSessions.php will then receive sessionA as an URL parameter and sessionB as a cookie, and update the session link table accordingly.
You could attempt to identify your visitors by IP, browser type, browser version, OS, screen resolution, and whatever else you come up with. That you store in the shared database when someone accesses either site.
If, within a small time window, say < 5 min, requests from that IP with those parameters comes, you can reasonably assume that it's the same user. Again, make sure you use everything you can find find to identify that user and by no means base anything secure on this or you will be subject to hijacking.
What about something like this, not sure how good it would be though.
User goes to store1. If user does not have a session cookie, redirect to a special page on store2 asking for the session id and sending the url on store1 to return to. The special page looks at the session cookie and redirects back to the original url on store1 with the session id (like the answer by #symcbean). Then on store1, the session cookie gets set(or created new) and no more redirecting happens. And then the same but oposite if the user is on store2 with no session cookie.
But if the user does not have cookies enabled, I can see an infinite loop happening. Not sure if it would be possible to detect and stop somehow.
But this way would be hacky at best.
1) Obviously, use the same session-store for both domains (files, database, memcached, the usual suspects.
2) If after session_start() the $_SESSION is empty, create an 'all domains' array in the session (do this on every domain, regardless which one it is, ).
$_SESSION['all_domains'] = array(
'domain1.com' => true, //<= current domain the customer is on,
'domain2.com' => false, //other domain, no cookie for it yet.
'domain2.com' => false); //repeat for all domains needed
3) Create a session-setter script on all domains (let's call it 'sesset.php':
<?php
if(isset($_GET['sessid']){
session_id($_GET['sessid']);
session_start();
//also, check here for the domains:
if(!isset($_SESSION['all_domains'])){
//set the array as before, flag this domain as true.
} else {
$_SESSION['all_domains'][$_SERVER['HTTP_HOST']] = true;
//you might want to set a custom domainname instead of HTTP_HOST, so you won't get doubles from domain with & without www. and so on.
}
}
?>
4) On every conceivable php HTML page, put this somewhere near the end of the body:
<?php
foreach($_SESSION['all_domains'] as $domain => $domainset){
if(!$domainset){
echo '<img src="http://'.$domain.'/sesset.php?sessid='.session_id().' width="1" height="1"/>';
}
}
?>
Not fullproof, but will get almost all users. Ofcourse, one could do it with a redirect cascade instead of 'hidden images', but searchbots (google et al.) very much get confused about it, especially if they don't remember the cookie and are stuck being redirected again & again.
easyXDM is a framework that allows the user to easily work around the Same Origin Policy.
Its built-in RPC feature is very easy to use, and you should be up in running in no-time.
For your case, select one of the domains to be the 'checkout'-domain (A) - this is the domain that will keep the session stored. On the same domain you create a small file with an easyXDM endpoint that is responsible for storing/retrieving the data sent from the other domain (B).
Now, in domain B, you include easyXDM and when storing/retrieving data from the cart, you access the RPC methods instead.
Option 1 Use Iframes:
Site 1 has an Iframe of site 2
Site 2 has an Iframe of site 1
When a user selects an item from site one, set the iframe value to a dynamic string ie domain2.com/iframe.php?itemid=someitem.
Have domain2 grab the $_GET information with PHP from the iframe and update the user's cookie.
Do the same in the other direction.
Option 2: Javascript includes
You can do something similar with cross-site included JS files generated by PHP to "pull" the contents of the user's cookie to the other site.
Option 3: Curl
Just post the data from one domain to the other, so both have a copy. This is the least secure method since there is no guarantee that the IP address or other identifying data can't be duplicated. Though, you can have some "question" or pass phrase to ensure it is the same person. Possibly by setting an email address?
Option 4: Third-party cookies
I think this one was already mentioned, but you can set the cookies from a third domain, so both sites functionally exactly the same rather than "toggling" back and forth between the two.

Categories