I have a users only section in my website, but on their first visit to the website (after having quit the browser or being on a new computer or not being logged in for a while), it will take them to the logged in home page fine, but when they try to navigate to a second logged in page from that home, they are automatically logged out. When they log in a second time, the effect is gone and everything works okay.
I have session_start(); at the top of every page.
This is how I generate a session when a user logs in:
session_regenerate_id(true); // destroying the old session id and creating a new one
$_SESSION['id'] = $login;
setcookie("id", $login, strtotime( '+30 days' ), "/", "", "", TRUE);
I have the sessions regenerate for security, but maybe I am doing it wrong and it's causing a problem?
Logged In check:
public function logged_in () {
return(isset($_SESSION['id'])) ? true : false;
}
public function logged_out_protect() {
if ($this->logged_in() === false) {
header('Location: index.php');
exit();
}
}
Related
Edited:
I am too sad that this question was downvoted, I was stuned by this for many hours.I wish there are a lovely alchemist who can make me back from debuff condition.
I am using codeigniter,I think the problem is when the new session (the session with flash message) is set, the session id (as a cookie) does not send to client, so after redirect to other pages, a fresh new session is created.
There is a problem in my log out function. The logic is simply click "log out", redirect to index page with a flash message--You have been log out.
After inspect, I found these things:the old session is clear with no problems, the new session is created before redirection, the new session do has flash message. Then the strange things comes, when redirected to index, a fresh newer session is created. But, If I do not run redirection after adding flash message, and click browser's refresh, then go to index manually, the session with flash message will be there and displayed perfectly.
I also found before redirection or refresh browser, though the session is recreated, there is no session id in my cookies. The refresh action sends session id to my cookies.
I hope I made the question clear. Thank you.
//auth controller
public function logout()
{
$this->my_auth_lib->logout();
$this->session->set_flashdata('alert','You have been logged out!');
redirect('index');
}
//my_auth_lib
public function logout()
{
return $this->session->sess_destroy();
}
// session library sess_destory method
public function sess_destroy()
{
// get session name.
$name = session_name();
if (isset($_COOKIE[$name])) {
// Clear session cookie
$params = session_get_cookie_params();
setcookie($name, '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
unset($_COOKIE[$name]);
}
$this->sess_create();
}
//session library sess_create method
public function sess_create()
{
$_SESSION[$this->sess_namespace] = array(
'session_id' => md5(microtime()),
'last_activity' => time()
);
// Set matching values as required
if ($this->_config['sess_match_ip'] === true) {
// Store user IP address
$_SESSION[$this->sess_namespace]['ip_address'] = $this->ci->input->ip_address();
}
if ($this->_config['sess_match_useragent'] === true) {
// Store user agent string
$_SESSION[$this->sess_namespace]['user_agent'] = trim(substr($this->ci->input->user_agent(), 0, 50));
}
$this->store = $_SESSION[$this->sess_namespace];
}
Try putting an
exit;
statement in the line right after the redirect
Got the idea from here
PHP: session isn't saving before header redirect
I created a relatively small php/mysql based website and hosted it on a server running Red Hat 6.4, Apache/2.2.15. In order to access the site, the users are required to authenticate.
Now comes the weird problem. When I start the server, the site initially runs fine, but after about 12-24 hours, the php sessions stop working. When users try to login, their credentials a successfully retrieved from the database and the login script sets up the session variables, but when they are redirected to the home page - the session variables are lost so the home page thinks they aren't logged in and they are redirected back to the login page. The site is not heavily used, there are about 50 registered users and there are under 100 logins daily. Also, the site requires an invitation code to register, so the probability for bots to be on the site is very small.
Below are the PHP functions used to start a session, to log the users in and to check if they are authenticated (the code was inspired from http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL):
function SecSessionStart() {
$session_name = 'sec_session_id'; // Set a custom session name
$secure = false;//https is not enforced
// This stops JavaScript being able to access the session id.
$httponly = true;
// Forces sessions to only use cookies.
if (ini_set('session.use_only_cookies', 1) === FALSE) {
header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
exit();
}
// Gets current cookies params.
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams["lifetime"],
$cookieParams["path"],
$cookieParams["domain"],
$secure,
$httponly);
// Sets the session name to the one set above.
session_name($session_name);
session_start(); // Start the PHP session
session_regenerate_id(); // regenerated the session, delete the old one.
}
function Login($username, $password) {
$username=trim($username);
if (CheckUserCredentials($username, $password))
{
$userId=GetUserIdByUsername($username);
$hashedPass=hash("sha512",$password);
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['user_id'] = $userId;
// XSS protection as we might print this value
$username = strtolower($username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $hashedPass.$user_browser);
// Login successful.
session_write_close();
return true;
}
else {
session_write_close();
return false;
}
}
function LoginCheck() {
// Check if all session variables are set
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string']))
{
$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$hash=GetPasswordHashByUserId($user_id);
if ($hash==null)
{
session_destroy();
session_write_close();
return false;
}
$login_check = hash('sha512', $hash.$user_browser);
if ($login_check == $login_string) {
// Logged In
session_write_close();
return true;
} else {
// Not logged in
session_destroy();
session_write_close();
return false;
}
}
session_destroy();
session_write_close();
return false;
}
In order to test my assumption that the problem was related to the sessions, I made the following php page and I've set up monitoring on it once every 5 minutes on an uptime checker:
<?php
require_once("include/authentication.php");
SecSessionStart();
$_SESSION['sessionCheck'] = "The cookie was successfully saved and retrieved";
session_write_close();
$_SESSION['sessionCheck']="";
SecSessionStart();
if (isset($_SESSION['sessionCheck']))
{
echo($_SESSION['sessionCheck']);
}
session_destroy();
session_write_close();
?>
Just as I suspected, the page returned the right answer for about 20 hours then I got an alert that the page was not displaying the success string. After I got the alert the login part on the site didn't work, either. I've tried to restart the httpd process to bring back to life the sessions, but this did not help. Only after a complete server restart things got back to normal.
I have tried searching on SO and other sites for my problem and I found some questions that were somehow related, but they did not entirely fit my situation. The main difference between my problem and other similar ones its that the site works perfectly fine in the beginning, but after some time the sessions fail all of the time. Other posters had problems where they lost sessions from time to time or the sessions did not work at all.
Any hint on the possible source of this problem would be kindly appreciated. If you need any further information from me that could help, please let me know.
Thank you
So here is my code that sends an expire time of a year if remember me is clicked.
And if not, then it sets the session_set_cookie_params() to 0. Which means that it should destroy the session when browser is closed. However it isn't working like that for some reason.
This is my login page:
session_start();
if (isset($_POST['username']) && isset($_POST['password'])) {
if (($_POST['username'] == $user) && ($_POST['password'] == $pass)) {
if (isset($_POST['rememberme'])) {
$_SESSION['username'] = $user;
$_SESSION['start'] = time();
$_SESSION['expire'] = $_SESSION['start'] + (60*60*24*365);
}
else{
$_SESSION['username'] = $user;
session_set_cookie_params(0);
}
header('Location: index.php');
} else {
$p->addContent('<font color = red>Wrong</font>');
}
}
This is my index page:
session_start();
if (isset($_POST['rememberme'])){
$user = $_SESSION['username'];
}
else {
$user = $_SESSION['username'];
session_set_cookie_params(0);
}
if ($user == null) {
$user = 'Guest';
$logout = $p->header()->addButton('Login', 'login.php', 'a', 'home', false, false, true);
$logout->rel('external');
}
else{
$logout = $p->header()->addButton('Logout', 'logout.php', 'a', 'delete', false, false, true);
$logout->rel('external');
}
It's quite simple. session_set_cookie_params(0); isn't affecting your session as you call it after calling session_start();.
Just reorder your code to something like this:
if (isset($_POST['username']) && isset($_POST['password'])) {
if (($_POST['username'] == $user) && ($_POST['password'] == $pass)) {
if (isset($_POST['rememberme'])) {
session_start();
$_SESSION['username'] = $user;
$_SESSION['start'] = time();
$_SESSION['expire'] = $_SESSION['start'] + (60*60*24*365);
} else {
session_set_cookie_params(0);
session_start();
$_SESSION['username'] = $user;
}
header('Location: index.php');
} else {
session_start();
$p->addContent('<font color = red>Wrong</font>');
}
} else {
session_start();
}
EDIT:
It's also worth nothing that session_set_cookie_params only work on the current script and has to be called again every time you use session_start(). It might me useful to set a cookie to indicate if it should used.
As of your code, session_set_cookie_params() isn't called in any case. Therefore I propose to do this:
session_set_cookie_params(0);
session_start();
if (isset($_POST['username']) && isset($_POST['password'])) {
...
Note, that's actually useful to call session_set_cookie_params() always for session cookies.
Generate a new session-ID at each user level change
To protect your applications against attackers, it is absolutely required to change the sessionID after each change of the role of a user:
Anonymous user -> Logged in user
Logged in user -> anonymous user
Logged in user -> Administrative logged in user
...
Thus, if user gets logged in or logged off, please regenerate the session ID like so:
session_regenerate_id( true );
Have a look in OWASP's PHP security cheat sheet.
Session-files get deleted regularly
Using PHP's standard session policy, sessions get mapped to regular files, so called session-files. If the user closes his browser, the session-file keeps living in the file system. Quite likely, the operation system is going to delete the session-file once a day (by night).
Thus, if a user comes back a day later, the sessionID cookie points to a session-file, which might no longer be available.
The case of public PCs
Additionally imagine a browser running on a public PC: If user closes his browser and a new user logs in, the other user gets automatically logged in.
UPDATED According to advice below. But still not working. Any help?
My company uses Active Directory LDAP and I'm using adLDAP to authenticate the user to login to this website.
So far, it works.. but every time they visit the page they must login again. The solution to this, I know is sessions. But I can't figure out what to store in the session in order to keep the user logged in.
This is included at the top of my login.php page:
auth.php
<?php
//include LDAP authenication script
require_once('LDAP/adLDAP.php');
$adldap = new adLDAP();
$username = $_POST['account'];
$password = $_POST['password'];
$authUser = $adldap->authenticate($username, $password);
$userinfo = $adldap->user_info($username, array("*"));
if ($authUser == true) {
$_SESSION['LDAP']['login'] = true
}
?>
Also at top of every page I have this:
<?php
if (empty('LDAP')) session_start();
if (!isset($_SESSION['LDAP']['login'] && $_SESSION['LDAP']['login'] !== true) {
header('Location: login.php');
exit; // dont forget the exit here...
}
?>
Right now, everytime I visit my index page index.php I log in, and I'm redirected to the main page. It works perfectly. But if I refresh the page, I'm asked to login again.
What do I store into a session so I don't have to log in everytime I refresh the page?
I know it starts with:
session_start();
But I don't know what to store in it?
You should only authenticate/include LDAP on your login page..
if success set a $_SESSION['LDAP']['login'] = true;
And check on every page with this.
if (!isset($_SESSION['LDAP']['login'] && $_SESSION['LDAP']['login'] !== true) {
header('Location: login.php');
exit; // dont forget the exit here...
}
Ok, having trouble here:
I created a login script, so after a person logs in then they will get direted to another page. And also, I have it redirecting them to the login page if they try and access one of those other pages.
My problem is, if a user is logged in and stumbles to the login page again --by accident-- I would like for it to recognize that the user is logged in and redirect them to that next page (which is index2.php) ?? Having troubles :-(
Here is my code so far:
require_once "inc/functions.class.php";
$quickprotect = new functions('inc/ini.php');
if (isset($_SESSION['goAfterLogin'])){
$goto = $_SESSION['goAfterLogin'];
unset($_SESSION['goAfterLogin']);
}
else $goto = $quickprotect->settings['DEFAULT_LOGIN_SUCCESS_PAGE'];
if (isset($_POST[username])) {
if($quickprotect->login($_POST[username], $_POST[password])) header ("Location: $goto");
}
Here is how I store a users session in the functions page
public function is_logged_in() {
//Determines if a user is logged in or not. Returns true or false;
if ($_SESSION['logged_in'] === md5($this->settings[ADMIN_PW])) {
return true;
}
else return false;
}
You don't mention how you store your users in your session, but something like this should do it for you:
if(isset($_SESSION['user']))
{
header("Location: index2.php");
exit;
}
This will check if you have a user in your session, and if so, redirect to index2.php.
You need to change 'user' according to your session key.