1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Is there such a thing as a unique browser $_SESSION id?

Discussion in 'PHP' started by qwikad.com, Sep 19, 2015.

  1. #1
    I am working on add to favorites add-on (where posts will be added to favorites by signed in users), but then I saw that craigslist lets anyone add favorites without them being signed in. How do they do that? Is there a unique $_SESSION id for a browser? Sorry if it's a silly question.

    As an example: http://orlando.craigslist.org/search/jjj (Click on any star to add to favorites. May not be available in IE 11).
     
    qwikad.com, Sep 19, 2015 IP
  2. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #2
    This is how sessions generally work:
    1. The session id is sent to the user when his session is created.
    2. It is stored in a cookie (called, by default, PHPSESSID)
    3. That cookie is sent by the browser to the server with each request
    4. The server (PHP) uses that cookie, containing the session_id, to know which file corresponds to that user.
    The data in the sessions files is the content of $_SESSION, serialized (ie, represented as a string -- with a function such as serialize) ; and is un-serialized when the file is loaded by PHP, to populate the $_SESSION array.

    Sometimes, the session id is not stored in a cookie, but sent in URLs, too -- but that's quite rare, nowadays.
    For more information, you can take a look at the Session Handling section of the manual, that gives some useful information.
    For instance, there is a page about Passing the Session ID, which explains how the session id is passed from page to page, using a cookie, or in URLs -- and which configuration options affect this.

    [Source]
     
    ThePHPMaster, Sep 19, 2015 IP
  3. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #3
    So first I need to create a cookie to be stored in this or that particular browser. Then that cookie will identify a user in a unique way. Am I understanding it right?

    PS to you they may seem like basic questions, but I am JUST delving into all of this. So be patient with me.
     
    qwikad.com, Sep 19, 2015 IP
  4. billzo

    billzo Well-Known Member

    Messages:
    961
    Likes Received:
    278
    Best Answers:
    15
    Trophy Points:
    113
    #4
    Do not forget that cookies can be created in Javascript. A cursory look at the JS indicates this may be the case (but I did not evaluate the code much). Javascript cookies are often used to store when a pop under is shown so it is not shown repeatedly. And it would not make sense for a round trip request to the server to be used to set a cookie in this type of situation.
     
    billzo, Sep 19, 2015 IP
  5. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #5
    Or FF, or Chrome, or Opera, or IE10/lower... Still no clue what you mean by "click on any star" on those pages.

    When you start a PHP session with session_start if the cookie does not exist a unique random one is created, and typically passed as a cookie. That's how sessions WORK. You don't need to create the cookie yourself, PHP does that FOR YOU.

    Keeping that cookie the same is a bad idea for handling a user login as it makes "man in the middle" attacks easier. Someone else gets hold of that session ID, they can hijack it. This is why it's recommended that immediately after session_start you do a session_regenerate_id which changes the session cookie and local hash to new values narrowing the window during which that existing ID is valid.

    So basically at the start of your program call:

    session_start();
    session_regenerate_id();
    Code (markup):
    ... and php will do the rest. The $_SESSION array will be unique to that user unless someone manages to hijack it by intercepting that cookie. SADLY that's how most all logins are handled as well, which is why website login security is something of a joke.

    You don't need to make the session cookie yourself, you don't need to dick around with the session cookie in your scripting, PHP will handle all that FOR YOU. Just be sure you start the session BEFORE you let PHP output ANYTHING as it's part of the HTTP headers. You let ANYTHING be output/echo for markup headers will be sent resulting in PHP throwing an error. That's why setting up sessions (and any other header things like gzip compression) are best as the very first thing any php file the user can/should call directly should do.

    Just beware that not all servers store sessions indefinately, you can configure how long they are good for in your php.ini file.
     
    deathshadow, Sep 19, 2015 IP
  6. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #6
    @deathshadow for crying out loud you can't see THESE stars?? :) The only time I don't see them is in IE 11.

    ScreenHunter_184 Sep. 19 22.01.gif

    Lots of info to process. Good stuff!!
     
    qwikad.com, Sep 19, 2015 IP
  7. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #7
    @deathshadow This is what I have now:

    session_start();
    $_SESSION['userid'] = $_COOKIE[$someid];
    Code (markup):
    How do I exactly replace it with:

    session_start();
    session_regenerate_id();
    Code (markup):
     
    qwikad.com, Sep 19, 2015 IP
  8. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #8
    Figured something out:

    
    ini_set('session.cookie_lifetime', 60 * 60 * 24 * 365);
    ini_set('session.gc-maxlifetime', 60 * 60 * 24 * 365);
    session_start();
    $new_sessionid = session_id();
    $_SESSION['userid'] = $new_sessionid;
    Code (markup):
    Obviously I don't need to keep it for a year.

    ** It's important to note that for this to work in Chrome one will also have to add session_write_close(); at the end of the script.
     
    Last edited: Sep 20, 2015
    qwikad.com, Sep 20, 2015 IP
  9. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #9
    Uhm you don't dick with the cookies yourself. AT ALL. You don't need to set $_SESSION['userid'] as session_start makes one and regenerate auto-changes it... sure session_id() will pull it, but there's NO reason to put it into a variable or to copy it into $_SESSION.

    You've got a ton of code there for nothing. You also shouldn't have to explicitly "close" the session, unless for some reason your script is hanging.

    You have your session started, the ID is auto-generated so you do NOT need to do a blasted thing with it... just start storing your actual DATA in the session. Remember that said ID also should be automatically changed on every pageload so it's NOT a fixed value EVER -- making it unsuitable for use on tying to a database (which is the only reason I could see in using it for anything in the first place)

    I don't quite think you are grasping what sessions are, or how they work.

    ... and no, I do not see those stars in any browser from here, never seen those on any Craigslist page. Even if I did I'd have no clue what they do and as such never click on them... from their placement I'd assume they were something the poster added or some such like topic icons in a forum.
     
    deathshadow, Sep 21, 2015 IP
  10. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #10
    Just to show you what I'm getting here in FF for that page:
    http://www.cutcodedown.com/for_others/qwikad/clFlorida.jpg

    Same in classic Opera, ChrOpera, Chrome, Vivaldi, IE 8, 9, 10, 11 and Windows 10 "edge". No clue on Safari on OSX, I'm not set up for testing that right now.

    NEVER seen those on any part of Craigslist that I can recall.
     
    deathshadow, Sep 21, 2015 IP
  11. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #11
    Do you have an ad blocker installed? There's a reason you can't see them.

    To your previous post, why would I need a session to be changed when browser closed. It defeats the purpose. I know it's an oxymoron: keep session alive. Session means it's temporary. But if it's destroyed when a browser is closed, I might as well let only signed in users use that option.

    Is doing this
    
    $session_expiration = time()+3600*24*2;// +2 days
    session_set_cookie_params($session_expiration);
    session_start();// ...
    Code (markup):
    would be a better thing or still garbage?
     
    Last edited: Sep 21, 2015
    qwikad.com, Sep 21, 2015 IP
  12. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #12
    If an adblock is blocking some sort of legitimate functionality on the page, it's not legit... and of COURSE I run an adblock. Like I trust the sleazeball scumbag scam artists known as advertisers? PLEASE...

    Where did anyone mention the browser being closed? You can open and close the browser until blue in the face and so long as the cookie is preserved (which they usually are) the session will still be valid.

    The only thing I said was to change the ID with session_regenerate_id on every PAGELOAD. This narrows the window in which a man in the middle attack could hijack the cookie. Since information in sessions is stored on the SERVER, simply changing the cookie ID does NOT delete any data stored in the session -- you're just changing the identifier.

    You're closer to working, though I'd lose the "variable for nothing"... and the expiration value sent to set_cookie_params is added to the timestamp internally, so you don't add time() to it unless you want to add the number of seconds since the unix epoch... which would be a hell of a lot more than two days. If using the function dont' add time() -- if you're screwing with the cookie directly, THEN you add time(). REALLY there should be no reason to be playing with the cookie or it's value.

    session_set_cookie_params(172800);
    session_start();
    session_regenerate_id();
    Code (markup):
    From there just set your session values.

    You seem to really be overcomplicating something simple -- I get the feeling there's some key detail of this your not finding or not understanding, but I'm not sure quite how to explain it or what you're missing about it. Starting a session and setting how long it expires isn't hard... It's two or three functions.
     
    Last edited: Sep 21, 2015
    deathshadow, Sep 21, 2015 IP
  13. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #13
    Coming from the master of overcomplication that sounds almost funny. What you're missing is I need to send that cookie value to add/remove file somehow right? How else do I send it to it UNLESS I do something like $new_sessionid = session_id(); AND it's true, sometimes I simply don't understand how it all works, so I do some research and try to explain it here the way I understand it so that someone would tell me how it's actually done. AND sometimes I simply pull stuff out of my arse.
     
    qwikad.com, Sep 21, 2015 IP
  14. NetStar

    NetStar Notable Member

    Messages:
    2,471
    Likes Received:
    541
    Best Answers:
    21
    Trophy Points:
    245
    #14
    I'm surprised you didn't know the answer to your own question.. You have been a member on here for a while and have built/owned web sites longer than that... You have over 3,000 posts which means you have read at least that many topics/posts. Heck you've even asked cookie related questions in the past.... I'm just surprised you never asked yourself "Hmm...if the visitor doesn't have an account what is the only possible way I could track his/her return to my site?"... Obviously a cookie. Without even thinking I'm willing to bet in the most simplest implementation (yet effective) the web site creates a simple ID stored in a cookie thatnever expires then uses that ID to fetch/add/update Bookmarks in the database...
     
    NetStar, Sep 21, 2015 IP
  15. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,151
    Likes Received:
    1,656
    Best Answers:
    29
    Trophy Points:
    475
    #15

    The thing is programming isn't what I do by profession or calling. It's something I just do as needed. I had never dealt with session cookies in the past (if I remember this right). Obviously I am familiar with cookies but the thing is you or popsicle or deathshadow, you do stuff out of a vast experience in programming. You know that stuff in and out. When I do it, I almost always have a ton of insecurity. "Will it work?" Will it not work?" "Am I doing this right?" etc. I know I am coming across as a third grader at times (at 47!), but it's because I have never seriously taken time to learn php/mysql. I am thinking of taking courses this year, actually. So now you know.
     
    qwikad.com, Sep 21, 2015 IP
  16. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #16
    Because the user cookie is handled transparently for you,. and cookies are sent with EVERY file request whether you use them or not -- you only need to send what's being added or removed to the list.

    For example, if you had a favorites.php (this is lacking some security I'd have in production code, it's just enough to show you how to use sessions)

    <?php
    /*
    	favorite.php
    	adds or removes a favorite to/from the session
    	
    	EXAMPLES:
    		/favorite.php?action=add&advert=50
    		/favorite.php?action=remove&advert=48
    		
    	RETURNS:
    		echo's string values as follows:
    		'true' if action was successful, 
    		'false' if action failed due to value not set
    		'error' if action exceeds limits (like adding too many values)
    		'unknown' if action is unrecognized.
    */
    
    define('MAX_FAVORITES', 15);
    
    session_set_cookie_params(172800);
    session_start();
    session_regenerate_id();
    
    if (!array_key_exists('favorites', $_SESSION)) $_SESSION['favorites'] = [];
    
    // make sure our needed values are set
    if (isset($_GET['action']) && isset($_GET['advert'])) switch ($_GET['action']) {
    
    	case 'add':
    		// if too many, return that the action failed
    		if (count($_SESSION['favorites']) >= MAX_FAVORITES) die('error');
    		// otherwise store it in the session
    		$_SESSION['favorites'][$_GET['advert']] = true;
    		die('true');
    	break;
    	
    	case 'remove':
    		if (array_key_exists($_GET['advert'], $_SESSION['favorites'])) {
    			unset($_SESSION['favorites'][$_GET['advert']]);
    			die('true');
    		}
    		die('false');
    
    }
    
    // gets to here, no action was taken so return false
    
    echo('unknown');
    
    Code (markup):
    You'd call the above via AJAX.

    A more robust version would probably limit it to a certain number of favorites added within a certain period of time, probably storing the time added for existing favorites instead of 'true' on the indexes. Since adding a favorite means you should already have the markup and/or DOM for the add client side, extract it there when adding returns true instead of passing the whole thing over the web again! Should probably also make sure that 'advert' is a valid integer and toss a error state for invalid values as well. You could cross-reference to make sure the advert actually exists by calling the DB, but honestly that would take more server load than just letting the 'list' on pageload handle removing invalid ones.

    Likewise it might be smart to make it have an 'AJAX' parameter like "AJAX=1" that if included, returns the string, but if not does a header() redirect back to the REQUEST_URI -- this would let you have anchors that handle this scripting off with a reload for graceful degradation, then have the AJAX calls enhance it if need be. Just be sure if going that route that said anchors are set to nofollow as you don't want search engines trying to add favorites.

    To output the list of favorites would go something like this:

    <?php
    /*
    	showlist.php
    	Simple example to show favorites stored in $_SESSION
    	
    	ASSUMES
    		$db is a connected PDO object
    */
    
    session_set_cookie_params(172800);
    session_start();
    session_regenerate_id();
    
    // don't output the favorites if they have none
    if (
    	array_key_exists('favorites', $_SESSIONS) &&
    	count($_SESSIONS['favorites'])
    ) {
    
    	/*
    		Since they may have been added out of order, sort them for viewing
    		You may or may not want to do this, up to you!
    	*/
    	ksort($_SESSIONS['favorites']);
    
    	/*
    		Let's use POEM -- prepare once, execute mostly -- to pull these
    		Some people will kvetch about the multiple queries, but for safety
    		sake, do it!
    	*/
    	$getFavorite = $db->prepare('
    		SELECT *
    		FROM adverts
    		WHERE id = :id
    	');
    	$getFavorite->bindParam(':id', $id);
    	
    	echo '
    		<div class="favorites">';
    		
    	foreach ($_SESSIONS['favorites'] as $id => $value) {
    		$getFavorite->execute();
    		if ($result = $getFavorite->fetch(PDO::FETCH_ASSOC)) {
    			// guessing wildly on table structure, adjust as needed
    			echo '
    				<div>
    					<a href="', $result['url'], '">
    						<img
    							src="', $result['img'], '"
    							alt="', $result['alt'], '"
    						>
    						', $result['content'], '
    					</a>
    				</div>';
    		} else {
    			// remove this favorite as it no longer exists
    			unset($_SESSIONS['favorites'][$id]);
    		}
    	}
    	
    	echo '
    		<!-- .favorites --></div>';
    		
    } else echo '
    	<p class="noFavorites">
    		No Favorites Found
    	</p>';
    
    ?>
    Code (markup):
    See, no need to be playing with the session ID, as the session handles that FOR YOU.

    BTW, this makes your other thread about limiting the number of values in the database for favorites obsolete. You've got a perfectly good session, you only want to retain these FOR the session, so don't get the DB involved in storing these.
     
    Last edited: Sep 21, 2015
    deathshadow, Sep 21, 2015 IP
    qwikad.com likes this.