Last time a user was logged in / browsing the website - php

I'm trying to set up a notifications system that doesn't requiere cookies.
I'm using SQL to store my users's info, and they are then passed into $_SESSION['user_auth'] once they are logged in.
When a user logs in, I want to fetch the last time the user was online (for instance 05/05/2016 21:35:50) and then compare with the database if there's any more recent announcements, posterior to its "last time logged in".
Is this viable ?
How can I know the last time my user was browsing the website ? Do I need a new row in my 'users' table, if so, how to set this function up ?
Thanks for your suggestions

I've got a similar method I created and you can see the answer here
The basic idea is updating a lastActive column in the database and update this upon user login and set a session variable to the current time. Then at the top of each page is a function that checks a users activity. If the time between last login and current time is above 45minutes then the lastActive data in MySQL is updated.
You can use the following function to set and update the lastActive column and use your own methods for 'when' this function can be used.
function set_last_active($mysqli, $username) {
if ($stmt = $mysqli->prepare("UPDATE Users SET lastActive = Now() WHERE username = ?")) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->close();
}
}
This is what I use as a script at the top of each page:
<?php
include_once 'functions.php';
if(isset($_SESSION['username'], $_SESSION['user_id'], $_SESSION['lastActive'])) {
date_default_timezone_set("Europe/London");
$now = new DateTime();
$lastActive = $_SESSION['lastActive'];
$diff=$now->diff($lastActive);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$day = $diff->format('%d');
$month = $diff->format('%m');
$year = $diff->format('%y');
if($mins > 45 || $hours >= 1 || $day >= 1 || $month >= 1 || $year >= 1) {
$_SESSION['lastActive'] = $now;
set_last_active($mysqli, $_SESSION['username']);
}
}

Related

Timer in PHP on registration

I want to make little timer on my registration, per user. So basically I want to make it when someone makes the account, they are put on timer for lets say 5 minutes before registering again (same user).
I've tried the below, but it doesn't seem to be working:
$now = date('Y-m-d H:i:s');
if ($stmt->num_rows > 0) {
exit('user already exists');
} else {
$expire = date('Y-m-d H:i:s',+30);
if($now>$expire) {
create new acc
} else {
exit('You need to wait.');
}
Just add "+ 5 min to expire" docs: https://www.php.net/manual/de/function.strtotime.php
$now = date('Y-m-d H:i:s');
if ($stmt->num_rows > 0) {
exit('user already exists');
} else {
$expire = date('Y-m-d H:i:s', "+ 5 minutes");
if($now>$expire) {
create new acc
} else {
exit('You need to wait.');
}
You can basically use this code it will work
this code snippet will not work. Both variables, $now and $expire, are defined on the same flow.
On time of evaluation, the expression $now>$expire is never true.
You need store the state for the lock. One way to achieve this is a cookie that carries the date of last registration attempt.
PseudoCode
if isRegistered(user): exit("Already signed up")
else if notSet(cookie['lastAttemptAt']) : proceedWithSignUp()
else if cookie['lastAttemptAt'].plus(5, Minutes) < now() : proceedWithSignUp()
else : exit("You need to wait")
in this case the function proceedWithSignUp needs to take care as well to set the cookie value of lastAttemptAt
Be aware, that this can be easily by passed, by either not accepting cookies at all or clearing the cookies.

Logout user after a specific time of inactivity

I am creating a website with more than 10 different php files. I want to check if the user is inactive, starting from the login page. So, if a user logs in and remains idle for a specific period of time, it has to log that user out. I am new to PHP and am currently using an answer to similar question which is
if (isset($_SESSION["LAST_ACTIVITY"])) {
if (time() - $_SESSION["LAST_ACTIVITY"] > 1800)) {
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
} else if (time() - $_SESSION["LAST_ACTIVITY"] > 60) {
$_SESSION["LAST_ACTIVITY"] = time(); // update last activity time stamp
}
}
I found the answer here:
expire session when there is no activity in PHP
I have created a separate page called session.php and pasted the code in the above link. Then I included the file session.php in my login page (which checks for the credentials entered and logs a user in). The problem is, the if loop is not being run and I do not know how to define $_SESSION['LAST_ACTIVITY'] variable. I used the following in my login page:
$query = "SELECT *
FROM user_details
WHERE username = '$username'
AND password = '$password'";
$result = mysqli_query($dbconnect, $query);
$row = mysqli_fetch_array($result);
$count = mysqli_num_rows($result);
if ($count == 1) {
session_start();
echo "Welcome " .$username. "</br>";
$_SESSION['username'] = $username;
$login_time = time();
$_SESSION["LAST_ACTIVITY"] = $login_time ;
include('session.php');
I also tried including session.php at the beginning of the file but of no use. The problem is: time() - $_SESSION["LAST_ACTIVITY"] is being equalled to 0. How do I store last activity time and compare it with the current time? Also, should I include session.php in every other webpage file for the website to check user activity ? If yes, should I include it at the beginning or at the end ?
This code will solved your problem for session timeout.
<?php
// set timeout period in seconds
$inactive = 60; //after 60 seconds the user gets logged out
// check to see if $_SESSION['timeout'] is set
if(isset($_SESSION['timeout']) ) {
$session_life = time() - $_SESSION['timeout'];
if($session_life > $inactive)
{
session_destroy();
header("Location: Logout.php");
}
}
$_SESSION['timeout'] = time();
?>

Limiting number of incorrect login attempts with timestamp

What is the correct way to let the user verify the captcha after 4 unsuccessfully login attempts within the last 15 minutes. I have got everything running fine but not timestamp part of the query. To be more specific it can display captcha after 4 failed attempts when user try to log in 5th time or so on, irrespective of whether 15min or 30min have passed...
$query1 = "SELECT login_attempts from users WHERE email = '$email' AND last_login < NOW() - INTERVAL 15 MINUTE";
$result1 = mysqli_query($dbc, $query1) OR die(mysqli_error());
$row = mysqli_fetch_array($result1);
$fail = (int)$row['login_attempts'];
If my understanding is correct, You have to check if the 4th last unsuccessful login attempt is before 15 minutes.
For achieving this, you have to store the time-stamps of last four unsuccessful logins in the database.
Create a field called unsuccesful_login_timestamps as text or varchar with large size in your db. We will store the UNIX timestamps of last four unsuccessful logins in comma separated form in this field.
When a user attempts to login, implement the following logic
If username and password is valid, let user login (You can clear the unsuccesful_login_timestamps field if login is succesful if you want). Else, run the following code.
$last_login_string = {{ get unsuccesful_login_timestamps value for this user from database }}
$last_login_string = update_last_login($last_login_string);
$fourth_last_login = get_4th_last_login($last_login_string);
$time_difference = time() - $fourth_last_login;
{{Update unsuccesful_login_timestamps in db with $last_login_string}}
if($time_difference <900){
//show captcha
}else{
//no_need_for_captcha
}
//Method to update last 4 unsuccessful logins by removing
// the last one from the starting and append the latest time in the end
function update_last_login($last_login_string){
$time_array = array();
if(strlen($last_login_string) > 0){
$time_array = explode(",",$last_login_string);
$size = count($time_array);
if($size ==0){ //first attempt
$last_login_string = time();
}else if($size == 4){ //>=4th attempt
$time_array[4]=time();
array_shift($time_array);
$last_login_string = implode(",",$time_array);
}else{ // >0, but <4 attempts
$time_array[$size]=time();
$last_login_string = implode(",",$time_array);
}
return $last_login_string;
}else{
return time();
}
}
function get_4th_last_login($last_login_string){
$time_array = array();
$time_array = explode(",",$last_login_string);
if($size !=4){
$last_login_time time();
}else{
$last_login_time = $time_array[0];
}
return $last_login_time;
}
I'm not terribly familiar with MySQL myself, but DATE_SUB may work:
SELECT login_attempts from users WHERE email = '$email' AND last_login BETWEEN DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND NOW()
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
EDIT: This answer is assuming that you are storing a timestamp (using time() or $_SERVER['REQUEST_TIME']) as the value of the last_login column in the users table.
What you can do is declare a $time variable using $_SERVER['REQUEST_TIME'] and do something like this:
$time = $_SERVER['REQUEST_TIME'] - 900; // Current time minus 900 seconds (15 minutes)
$query1 = "SELECT login_attempts from users WHERE email = '$email' AND last_login < $time";
If you want to change the time duration, just change the 900 to whatever value (in seconds) you want.

compare if date from database is bigger than current date

I'm stuck on this one.
It sounds quite easy what I'm trying to accomplish, still I can't get it to work...
I have several user stored in a database. They can visit a page after login. But each user has an end date. So if this day has passed, he won't be able to see the page anymore and will be redirected to another page. But there is a different date for each user.
When an user enter his credentials, a $_SESSION is created that stores his login name. I need the sql to get the date from the specific user using this $_SESSION value.
What I have so far:
$sql="SELECT * FROM $tbl_name WHERE licentiehouder=$naamLicentiehouder";
$naamLicentiehouder = $_SESSION['doorsturen'];
$result=mysql_query($sql);
$row = mysql_fetch_row($result);
$mydate = $row['vervaldatum'];
$curdate=strtotime("now");
if($curdate <= $mydate && $_SESSION['doorsturen'] == 'userONE') {
header("Location: userONE.php");
} else if ($curdate <= $mydate && $_SESSION['doorsturen'] == 'userTWO') {
header("Location: userTWO.php");
} else if($curdate > $mydate) {
header("Location: extend_license.php");
}
So again, every user has it's own license, which will expire on an exact date. This date is stored in the database. So if userONE's logging in, $_SESSION value is set to userONE. sql reads this values and gets only the row that's matching this value. If today (current date) is bigger than the date stored (so his license is expired), he will be redirected to a page to extend his license. If not, he will be able to see his personal page.
Hope anyone can help?!
Your variable $naamLicentiehouder is undefined at the time you run your query. Try:
$naamLicentiehouder = $_SESSION['doorsturen'];
$sql="SELECT * FROM $tbl_name WHERE licentiehouder='$naamLicentiehouder'";
Also mysql_query(), and the like, are depreciated. Use mysqli. I prefer the Object Oriented approach, since it saves a lot of repetitive typing.
To clarify, the Object Oriented approach, on a separate restricted page we'll call connect.php:
<?php
// reusable db() function can be called inside other functions
function db(){
return new mysqli('host', 'username', 'password', 'database');
}
?>
Now on your other page:
<?php
include_once 'restricted/connect.php'; $db = db();
if($db->connect_error)die("Connection Failure: {$db->connect_error}");
$naamLicentiehouder = $_SESSION['doorsturen']; // I would shorted this variable
if($result = $db->query("SELECT vervaldatum FROM your_table_name WHERE licentiehouder='$naamLicentiehouder'")){
if($result->num_rows > 0){
$row = $result->fetch_object(); $mydate = $row->vervaldatum;
$curdate = strtotime('now');
if($curdate <= $mydate && $naamLicentiehouder === 'userONE'){
header('LOCATION: userONE.php'); die;
}
elseif($curdate <= $mydate && $naamLicentiehouder === 'userTWO'){
header('LOCATION: userTWO.php'); die;
}
elseif($curdate > $mydate){
header('LOCATION: extend_license.php'); die;
}
else{
die('Date Issue.');
}
}
else{
die('No results were found.');
}
}
else{
die('Error :'.$db->error);
}
$result->free(); $db->close();
You seem to be getting a timestamp with $curdate=strtotime("now"); What you are getting from the database is likely (although I can't be sure) a date, not a timestamp. Use strtotime on it too:
$mydate = strtotime($row['vervaldatum']);
That should do it.

php and mysql send user to logout on time

When users login their online status is set to 1 when they logout its set back to 0, im trying to make it so after a certain amount of time of inactivity on the site they will be sent to logout.php, so I setup a field in my users table as last_activity as a timestamp. and have this code as a include on each page.
<?php
if (!isset($_SESSION['last_activity'])) {
// initiate value
$_SESSION['last_activity'] = time();
}
if (time() - $_SESSION['last_activity'] > 500) {
// last activity is longer then certain amount of time
header('Location: logout.php');
} else {
// update last activity timestamp
$_SESSION['last_activity'] = time();
}
?>
But right now as I have it, the last_activity field only updates when something on the users account is updated, also after the certain amount of time the user isn't logged out and I don't know why.
From automatic logout after 15 minutes of inactivity:
<?php
session_start();
$timeout = 10; // Set timeout minutes
$logout_redirect_url = "index.php"; // Set logout URL
$timeout = $timeout * 60; // Converts minutes to seconds
if (isset($_SESSION['start_time'])) {
$elapsed_time = time() - $_SESSION['start_time'];
if ($elapsed_time >= $timeout) {
session_destroy();
header("Location: $logout_redirect_url");
}
}
$_SESSION['start_time'] = time();
?>
Your code is right just at the top of the file you have to start the session with session_start()

Categories