Avoiding people to refresh page? - php

i have some problem, i create a page to read news and if the page open it will be update in my database field for news_read +1 but i want if page refresh by user isn't +1
this is my query in page
$q="SELECT*FROM t_news WHERE news_id=$b_id";
$dataJ=mysql_query($q);
$a=mysql_fetch_array($dataJ);
$plus=$a['news_read']+1;
mysql_query("UPDATE t_news set news_read=$plus WHERE news_id=$a[news_id]");
anyone know, how to disable $plus=$a['berita_dibaca']+1; after refreshing the page?
UPDATE
UPDATE
thanks all ,i have solved my problem with session
i put
if ($_SESSION['load']==1){
$_SESSION['load']=0;
}
in all of my page except read.php and i put
if ($_SESSION['load']==0)
{
//QUERY
}
$_SESSION['load'] = 1;
in read.php

Method 1.
Save cookie, if user has cookie don't update database.
Method 2. (better)
Save users who have already viewed this article, and if user is in list do not update database.
Tip:
UPDATE t_news set news_read = news_read + 1 WHERE news_id = $a[news_id]
to avoid useless queries.

That's not a question to solve with sql, but with HTTP.
There is basically no difference between a refresh of a page and the inital request. There both just HTTP commands. There may be a difference in the headers of both requests but you can't always be sure they are present. So using the referer is probaly not a great idea.
Beside Valdas answer with the cookie you may also use the session of your user and set a flag there. (Although most session implementations do also use cookies, but in another way)

This method doesn't require a user to be logged in:
session_start(); // ignore if you're already using sessions
if( !isset($_SESSION['has_read_news'])) $_SESSION['has_read_news'] = array();
if( !isset($_SESSION['has_read_news'][$b_id])) {
mysql_query("UPDATE `t_news` SET `news_read`=`news_read`+1 WHERE `news_id`=".$b_id);
$_SESSION['has_read_news'][$b_id] = true;
}
Note that it's not completely foolproof (clearing the session cookie will allow the user to be counted again) but overall it should be plenty good enough.

Related

Set cookie and redirect if cookie set based on url

I am running woocommerce/wordpress and noticed customers refreshing the thankyou page cause google analytics to record multiple transactions.
The url they visit is: /checkout/order-received/24420/?key=wc_order_a5m1jzQDJLjjr
I figure i need to Set a cookie using that order number. If cookie exists then redirect before analytics code runs. Thus preventing reloads of thank you page.. (i hope)
I don't know who to extract the number 24420 from the url and set a cookie. Redirecting on Cookie i can figure out.
thanks
/J
To retrieve the Order ID
$order_id = wc_get_order_id_by_order_key( $_GET['key'] );
I would suggest to use a session instead of cookie so you can do something like
if(isset($_SESSION['order_'.$order_id])) {
header("Location: /where-you-want");
die;
} else {
$_SESSION['order_'.$order_id] = 1;
}
Please note that both Session and Cookies need to be set before any other output on the page, so be sure that the code you're running is executed before any HTML is printed.

Handle $_SESSION through pages in a php site

I googled to solve my question but any site explains my problem in a different way so I feel very confused!
I realized a php site in this way.
index.php:
In this page I get username and passw from login form and after checked if the user really exist I'll save them first in a variable and after in session.
$_SESSION['user']=$user;
$_SESSION['psw']=$psw;
Now I would show this page ONLY if the user is logged, so I would make some like this:
first_page.php:
<?
if(isset($_SESSION['user']) && isset($_SESSION['user'])!="" && isset($_SESSION['psw']) && isset($_SESSION['psw'])!=""{
// show page site
}
else
// go to index.php
?>
and insert this block if-else in any pages of the site.
It is correct this procedure?
I need to introduce session_start(); in any page or just in index.php?
How long time $_SESSION['user'] and $_SESSION['psw'] (expires)?
Since the site needs $_SESSION['user'] for many features, I need to be sure that when a user navigate the site those session variables are setted.
Thanks for your support, I feel very confused on it.
You must add session_start() in every single page where you use $_SESSION. It expires when you leave the site.
Don't store a password in a session, without changing the session handler data in a session is stored as plain text outside of the web root. This means anyone that has access to the system can read session data.
The method of knowing if a valid login occured is:
$sql = "select id where username = 'username' and password = 'hashedpassword'"
If an id is returned it means the user successfully logged in and store that ID in a session. Then validate if the session continues if the ID is set.
Keep in mind that after raising privileges it is recommend to change the session id as well, that can be done with session_regenerate_id() this to add protection for session fixation attacks.
At the beginning of each script when trying to read data from a session use session_start() and session_destroy() to remove all data stored in that session (usually a logout)
If I introduce at the top of any page the following script, could be a good solution? Or there's something wrong?
if ((isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) || $_SESSION['iduser']==NULL) {
// last request was more than 30 minutes ago
session_unset();
session_destroy(); // destroy session data in storage
echo "<script>location.href='index.php'</script>"; //redirect the user to index page
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
/* Code for the rest of my page HTML*/
(took from here: How do I expire a PHP session after 30 minutes?)

Set and Check Cookie in the one response - Laravel

I am attempting to set a cookie and then check to see if the cookie has been set.
So in one function, I have it make the cookies:
public function makeCookies(){
Cookie::queue('logged_in', $value, 15);
Cookie::queue('user_id', 2);
//return Response::make()->withCookie(Cookie::make('logged_in', $value, 15))->withCookie(Cookie::forever('user_id', 2));
}
And in the other function, I try to check to see if the cookie has been set:
public function checkCookies(){
$this->makeCookies();
if(Cookie::get('logged_in') && Cookie::get('user_id')){
return 'Logged In!';
}
}
However the only way this works is if I add 'return' before $this->makeCookies(); However, I want to be able to get to the conditional below it. Is there any way I can go about doing this? Any help is greatly appreciated.
To understand the Cookie Creation/Read process:
The user's browser sends a request for a page, along with any cookies that it currently has for the site
The site serves up the page, and any cookies you create become a header in your response.
Subsequent requests to your site will send the cookies created in #2.
What you are asking...to be able to read cookies that you create in step #2 in step #1...not possible.
Now, depending on how the Cookie class is created, you could make it so that when the Cookie::queue() is called, that it creates in-memory data that reflects what the cookie "should be" on the next request, but it doesn't truly know whether or not the user's browser will accept cookies, etc.
This is why many sites, after creating a cookie give the user a redirect to a page with something like ?checkCookie=1. This way, on the subsequent request, they can verify that your browser supports cookies...and if the cookie doesn't exist on the ?checkCookie page, they give you an error saying that their site requires cookie support. However, it does require a second round to the server to read cookies from the browser that were created.
UPDATE 2015-04-24 Per #Scopey, Laravel does support in-memory retrieval of cookies via queued(). So, you should be able to do:
public function checkCookies(){
$this->makeCookies();
$loggedIn = Cookie::get('logged_in') ?: Cookie::queued('logged_in');
$userId = Cookie::get('user_id') ?: Cookie::queued('user_id');
if( $loggedIn && $userId ){
return 'Logged In!';
}
}
SECURITY CONCERNS (NOT DIRECTLY ANSWERING THE QUESTION)
Your question was only about the cookies, so that's all I answered. However, now that I'm looking at your code, I feel I would be remiss not to point this out for anyone that happens to be reading this. This may just be a "how to" for yourself and not production code, but that code could be very dangerous if it ever went public.
Make sure you do NOT TRUST a user_id stored in a cookie to determine what user is coming in via cookies. If you rely on that, and I come to your site, I can modify my cookie to any user_id I want and get into other people's accounts.
General Safety Rules:
A cookie should contain a GUID, or similar random string to identify the session. This random string should be sufficiently long (e.g. 32 characters or greater, IMHO) that it is not easy for someone to brute-force their way to hijacking sessions.
The user_id should be stored in the $_SESSION (or laravel's wrapper for session if applicable) so that the user doesn't have any access to the user_id to be able to modify it.
In plain PHP, this something like this for the login page:
session_start();
if( isValidPassword($_POST['username'], $_POST['password']) ) {
$_SESSION['user_id'] = $user->Id;
}
else {
die('invalid login credentials');
}
The session_start() method automatically generates a cookie for the user with that long, random string (so you don't even have to worry about that part.)
On subsequent pages, you just check the session user_id to know who is logged in:
session_start();
if( empty($_SESSION['user_id']) ) {
die('You are not logged in and cannot access this page');
}
Change as needed per Laravel's documentation, which if they have their own session wrapper, I'm sure is well documented on best practices.
Excellent description by #KevinNelson about cookies but Laravel does support fetching back any cookies you have queued in the current request. Try using
Cookie::queued('logged_in');
The catch is, the cookie will only be "queued" during the request that you queued it. You will have to use get like you are for any other requests.

Force user to logout session PHP

I can't seem to find a straightforward answer to this question. Is there a way in which I can force a logged in user to logout? My login system essentially just relies on a session containing the user's unique ID (which is stored in a mysql database). So essentially just...
if (isset($_SESSION['user_id'])) {
echo "You're logged in!";
} else {
echo "You need to login!";
}
But let's say I want to ban this user, well I can change their status to banned in my database but this won't do anything until the user logs out and attempts to log back in... So, how do I force this user to logout? Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server. Any help is appreciated, thank you.
Either you need to check every time they load a page, or possibly look at an Ajax call at set intervals to check their status from the DB.
Then you can use session_destroy(); to end their session. This will destroy their entire session.
Otherwise you can use unset($_SESSION['user_id']); to unset a single session variable
Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server.
Loading the user from the database on every page load, rather than storing a copy of the user in the session, is a perfectly reasonable solution. It also prevents the user from getting out of sync with the copy in the database (so that, for instance, you can change a user's properties or permissions without them having to log out and back in).
Try to put this on every page...
if (isset($_SESSION['user_id'])) {
$sql = "SELECT from tbl where status='banned' and user_id=$_SESSION['user_id'] ";
$query = mysql_query($sql);
if(!empty(mysql_num_rows($query))){ // found the banned user
//redirect to logout or
//session_destroy();
}
} else {
echo "You need to login!";
}
if the user is still logged in... check if his/her status is banned or not... if banned.. then logout
You can unset it.
unset($_SESSION['user_id'])
You could use Custom Session Handlers this way you have full control where and how the session data is stored on the server.
So you could store the session data for a particular user in a file called <user_id>.session for example. Then, to logout the user, just delete that file.
Ajax calls in an interval will put extra load on server. If you want real-time response to your actions(e.g. the user will be signed out right when you ban them from your system backend), then you should look into something like Server Push.
The idea is to keep a tunnel open from Server to Browser whenever a user is browsing your website, so that you can communicate with them from server-side too. If you want them to be banned, push a logout request and the process that in your page(i.e. force logout by unsetting session).
This worked for me am using pHP 5.4
include 'connect.php';
session_start();
if(session_destroy())
{
header("Location: login.php");
}
You can use session_save_path() to find the path where PHP saves the session files, and then delete them using unlink().
Once you delete the session file stored in the sever, the client side PHPSESSID cookie will no longer be valid for authentication and the user will be automatically be logger out of your application.
Please be very careful while using this approach, if the path in question turns out to be the global /tmp directory! There's bound to be other processes other than PHP storing temporary data there. If PHP has its own directory set aside for session data it should be fairly safe though.
There is a few ways to do this the best in my opinion based on security is:
NOTE: THIS IS REALLY ROUGH.... I know the syntax is wrong, its just for you to get an idea.
$con = mysql_connect("localhost","sampleuser","samplepass");
if (!$con)
{
$error = "Could not connect to server";
}
mysql_select_db("sampledb", $con);
$result = mysql_query("SELECT * FROM `sampletable` WHERE `username`='".$_SESSION['user_id']."'");
$userdeets = mysql_fetch_array($result);
if($_SESSION['sessionvalue'] != $userdeets['sessionvalue'])
{
session_destroy();
Header('Location: logout.php');
}
else
{
$result2 = mysql_query("UPDATE `sessionvalue` WHERE `username`='".$_SESSION['user_id']."' SET `sessionvalue` = RANDOMVALUE''");
$sesval = mysql_fetch_array($result2);
$_SESSION['sessionvalue'] = $seshval
}
Now I know thats not the very code but in essence what you need to do to be secure and have this ability is:
Everytime a page load check a Session value matches a value in the DB.
Every time a page loads set a new session value based on a random generated DB value. you will need to store the username in a session as well.
if the Session ID's do not match then you destroy the session and redirect them.
if it does match you make the new session ID.
if you want to ban a user you can set their sessionvalue in the DB to a value like "BANNED". this value will not allow them to log in either. this way you can control user through a simple web form and you can also generate list of banned users very easily etc etc. I wish I had more time to explain it I hope this helps.

Get original URL referer with PHP?

I am using $_SERVER['HTTP_REFERER']; to get the referer Url. It works as expected until the user clicks another page and the referer changes to the last page.
How do I store the original referring Url?
Store it either in a cookie (if it's acceptable for your situation), or in a session variable.
session_start();
if ( !isset( $_SESSION["origURL"] ) )
$_SESSION["origURL"] = $_SERVER["HTTP_REFERER"];
As Johnathan Suggested, you would either want to save it in a cookie or a session.
The easier way would be to use a Session variable.
session_start();
if(!isset($_SESSION['org_referer']))
{
$_SESSION['org_referer'] = $_SERVER['HTTP_REFERER'];
}
Put that at the top of the page, and you will always be able to access the first referer that the site visitor was directed by.
Store it in a cookie that only lasts for the current browsing session
Using Cookie as a repository of reference page is much better in most cases, as cookies will keep referrer until the browser is closed (and will keep it even if browser tab is closed), so in case if user left the page open, let's say before weekends, and returned to it after a couple of days, your session will probably be expired, but cookies are still will be there.
Put that code at the begin of a page (before any html output, as cookies will be properly set only before any echo/print):
if(!isset($_COOKIE['origin_ref']))
{
setcookie('origin_ref', $_SERVER['HTTP_REFERER']);
}
Then you can access it later:
$var = $_COOKIE['origin_ref'];
And to addition to what #pcp suggested about escaping $_SERVER['HTTP_REFERER'], when using cookie, you may also want to escape $_COOKIE['origin_ref'] on each request.

Categories