Destroy / Restart a different session in PHP - javascript

I always found solutions to my problems here, but I'm missing something for this one. Here's my problem:
I have a login.php page which redirects people to different pages depending on their status (member, expert, admin). The type of the button is a submit button:
<input type="submit" name="LOGIN" ...
I get all the info (login, password) of the form in my PHP using :
if(isset($_POST['LOGIN'])) { ...
And the user is redirected to its page with certain privileges.
But if the user has the status "member", that means it's his first visit and he has to go to an intermediate page (loginNewMb.php) using Header("Location: loginNewMb.php"); to enter his coordinates (name, company...). Then, he will have the status "registered member" and he will be able to go to his data.php?member=XXX page. But when he enters to the loginNewMb page, he's still in the session coming from the login.php page. So I need to close it and create a new one depending on the info he will provide. Hope you're still with me.
I was just wondering if you could please guide me as the best strategy to do that. How and in which files should I destroy / restart a new sessions? Is there a better way to do that? I don't necessarily need some codes, just some clues to guide me.
Thank you

To be sure, you can put the following at the beginning of your loginNewMn.php file.
/** clear session variable */
session_unset();
/** destroy the session */
session_destroy();
/** end the current session and store session data. */
session_write_close();
/** clear cookies */
setcookie(session_name(), '', ['expires' => 0, 'path' => '/']);
/** clear old session id */
session_regenerate_id(true);
/** start the (new) session */
session_start();

You can do a session_destroy() and session_regenerate_id(true) on top of the loginNewMb.php page.
Or you can unset specific $_SESSION variables using $_SESSION["foo"]
Or, you can just do it in the login.php before redirecting.
Note:
After you use session_destroy(), you have to use session_start() again to use $_SESSION variables.
Doing that with JS would not be really good, because any user can disable JS. So, using PHP is the best method.

Related

Check if a $_SESSION variable is set from Javascript

I'm building a message system to learn how it works, and I've already got
pretty much everything. I can log in and make a post on a board, but now I would like to be able to edit it. The back-end is ready, it receives a POST request
Basically what I need to do is check if the currently logged in user is the author of a certain post from Javascript to show or hide the edit button. I know how to tell if the user is logged in from PHP so that it blocks requests if you aren't the author, but I can't hide or show the buttons as the posts are dinamically generated from a <template> using JS.
Login snippet:
$_SESSION["userid"] = $userid;
Edit check PHP snippet (kinda pseudo-code):
if ($_POST["action"] == "modifypost" && isset($_POST["postid"]) && isset($_POST["content"]))
{
$post = get_post($_POST["postid"]);
if ($post.userid != $_SESSION["userid"])
{
die("you are not allowed");
}
//MySQL queries
}
Post dynamic generation (abbreviated):
function add_post(post) {
var t = document.querySelector('#historypost');
t.content.querySelector(".content").innerHTML = post.content;
var clone = document.importNode(t.content, true);
document.body.appendChild(clone);
}
I had originally thought of setting a variable with the user ID from HTML with <script> and <?php ?>, but then the user would be able to manually set that variable from the console and show the buttons.
I had originally thought of setting a variable with the user ID from HTML with <script> and <?php ?>
Yes, this is one correct approach. Basically, use PHP to tell JavaScript which posts actually belong to the current user.
but then the user would be able to manually set that variable from the console and show the buttons
True. There is no way to secure information from user-meddling once you've sent it to the browser. This is because the user is in control of what gets executed in the browser. Instead of thinking of the button visibility as a security feature, think of it as a convenience -- something to make the user experience more pleasing.
Application security is really enforced on the server. Just make sure that one user is not allowed to edit another user's posts, and do not trust what comes from the browser. Verify inputs.
Ideally, I would prefer to put the post rendering logic inside the server-side.
But as your solution is focused in javascript, an option makes PHP render a javascript variable that tells if the user is the post author.
Example:
Inside your PHP file, in the HTML render part you can do this:
<script>var isAuthor = '<?php echo ($post.userid == $_SESSION["userid"])'; ?></script>
Doing this you will have javascript script variable called isAuthor, that will have value "1" is the user is the author.
-
But as I said, this doesn't look like a good approach to solve the problem. It's something that PHP can handle better, without expose your logic to the client.

Implementing cookies with JS to recognize returning visitors

I have a blog with locked content. User needs to enter their email address into a form in order to see the full content.
Problem now is that the same user has to enter their email on every post. How do I implement cookies so that:
1) on a form submit, user gets a cookie
2) on a blog page load, check to see if cookie exists, and if it does, load the full content
--
I have minimal experience using cookies. Thanks!
Creating JS cookies on the front-end is simple:
document.cookie="email=foo#bar.com";
Which creates a cookie named "email" that has a content of "foo#bar.com."
When a user goes to your site again, you can check whether the cookie exists.
if (document.cookie.indexOf("email")>=0) {
// Log them in!
}
else {
// Show log-in field!
}
You might also want a cookie to expire after a certain period of time. When you create a cookie, you can set an expire date:
document.cookie="email=foo#bar.com;expire=06/12/2015";
However this isn't as secure as using sever-side cookies.
Cookies on the client will not give you the protection you seek because anyone with a browser could insert these cookies themselves. Moreover - client-side security over server-side content (the articles) inherently doesn't work. Any clever user will be able to get over any form of security measure that is not on the server.
That said, if you're entirely OK with users who do not install a specific extension or run a specific script to "unlock" your site - you can do something along the lines of:
if(document.cookie.indexOf("entered_email=true") === -1){
// show email request field
} else {
// show content
}
And when the user enters their email:
document.cookie += (document.cookie ? ";" : "") + "entered_email=true";
You could probably use the localStorage object for this:
HTML:
<input type="text" id="email"/>
<input type="button" id="submit" value="submit"/>
JS:
$(document).ready(function(){
if (localStorage.getItem("email")){
$("#email").val(localStorage.getItem("email"))
// unlockContent();
// otherStuff();
}
$("#submit").click(function(){
localStorage.setItem("email", $("#email").val());
alert("Saved: " + localStorage.getItem("email"));
// unlockContent();
// otherStuff();
})
})
Fiddle: here.
edit: but as Benjamin mentioned in his answer, this is not really a secure mechanism -- unless you simply want to verify an email rather a particular email.

Tab specific cookies without using sessionStorage or any HTML5 features

I am interested in having users be able to login and logout with multiple user session cookies on my web app. Currently, authentication is done standard and a unique identifier allows me to authenticate a user when they visit our site back if they present an auth token that's available in their cookie. Typical use cases apply in that if the user logs out from one tab, it logs them out of another tab. Right now it requires having the user login from two unique browser instances in order to be able to login to two different accounts.
Is there a non-HTML5 way (using standard javascript cookies) to have tab-specific cookie identifiers? I'm assuming that there is no clear cut way of going about this and it would require some kind of hack + cooperation from the backend. If there is a solution that makes sense without using HTML5, that would be ideal.
You can't.
There are ways to deal with this condition, but none of them are simple.
If you want, you have to tell user to do like this: How to geek
From docs: Data stored using sessionStorage do not persist across browser tabs, even if two tabs both contain webpages from the same domain origin. In other words, data inside sessionStorage is confined to not just the domain and directory of the invoking page, but the browser tab in which the page is contained in. Contrast that to session cookies, which do persist data from tab to tab.
I achieved similar behavior some time back. So, what I do is something like this:
For this to work, you need to carry the sessionId in the url or as part of the page content.
When login page is loaded, delete the sessionId cookie.
When login for is submitted, server gives you login page along with sessionId in the url or as part of html response body.
From now onwards, before every server call, set the session cookie to the one that you have in the url or page content.
So, each tab will set its own cookie before any server call which would make the request land with the right session on the server.
Before anything, this solution works if you use relative URLs only! (for images, links and even Ajax calls)
Use sessions as you would in any ordinary scenario with one small change. Instead of identifying users with each session ID, you will identify a machine (a browser) by each session ID. So when requests arrive at server, it identifies a bunch of users who are using your website on that computer. Each user will have his own sub-identifier (it could be a sequential counter or a random number). Putting it simple, your session data (identified by session ID in the cookies) holds an associative array. Each entry of this array holds session data for one particular user identified by sub-identifier. For instance, in PHP, if your user's sub-identifier is user0, then you can access this user's session data like:
<?php
session_start();
$user_data = $_SESSION['user0'];
Next is how to pass on user's sub-identifier.
You can use webserver's URL rewrite. You need to come up with a pattern which can be considered as an ordinary folder name, while there's no folder named like that. For instance:
RewriteEngine On
RewriteRule ^user(\d+)\/(.*)$ $2?sub_id=$1 [QSA,L]
In this example, you are not allowed to have any folders like user0, user1 etc. If some request asks for http://domain.com/user0/index.php it will be rewritten to http://domain.com/index.php?sub_id=user0. Now in index.php you'll have:
<?php
session_start();
$user_data = $_SESSION[$_REQUEST['sub_id']];
And you should use $user_data instead of $_SESSION from this point forth. The only thing that remains is how to generate sub-identifier for the first time. That's relatively easy, you can:
<?php
session_start();
if (!isset($_REQUEST['sub_id'])) {
$sub_id = 0;
while (isset($_SESSION["user{$sub_id}"])) {
$sub_id++;
}
$_SESSION["user{$sub_id}"] = array();
header("Location: /user{$sub_id}".$_SERVER['REQUEST_URI']);
die();
}
else {
$user_data = $_SESSION[$_REQUEST['sub_id']];
}
At the end, everything will work only if all your URLs are relative! Each absolute URL which does not start with /user0/ will be considered a new user and will lead to a new entry in the session.
The benefit of this approach is that your current code will work with minimum effort, as long as URLs are already addressed relatively.
This is a simple example of how you can create a system in which a user can log in to multiple accounts. This is no safety checks and must be added. This code can be much better to write and optimize.
inc.php
https://github.com/maksa9/multiple-user-login/blob/master/inc.php
This file is included into each php script.
This part check which user is logged and which account is active. Here are functions that create the proper path to the php scripts according to the active account
// check which user is logged and which account is active
if(isset($_GET['user'])) $id_user = (int)$_GET['user'];
if($id_user > 0)
{
if(isset($_SESSION['user'][$id_user]))
{
$user_name = $_SESSION['user'][$id_user]['name'];
$user_email = $_SESSION['user'][$id_user]['email'];
}
else
gotToLoginForm();
}
// If the user id is not specified and there is a user session, finds another id
if($id_user == 0 and isset($_SESSION['user']))
{
$sess = $_SESSION['user'];
$id_user = (int)key($sess);
if(isset($_SESSION['user'][$id_user]))
{
$user_name = $_SESSION['user'][$id_user]['name'];
$user_email = $_SESSION['user'][$id_user]['email'];
define('ID_USER',$id_user);
gotToIndex();
}
else
gotToLoginForm();
}
define('ID_USER',$id_user);
loginform.php
https://github.com/maksa9/multiple-user-login/blob/master/loginform.php
Simple form to login with post method.
login.php
https://github.com/maksa9/multiple-user-login/blob/master/login.php
Login user. simulates a query to the database.
if(isset($_POST['email']))
if(isset($_POST['pass']))
{
$email = $_POST['email'];
$pass = $_POST['pass'];
$id_user = 0;
// simulates a query to the database
if($email === 'test1#test.com' and $pass === '111')
{
$id_user = 1;
$name='John Doe';
}
if($email === 'test2#test.com' and $pass === '222')
{
$id_user = 2;
$name = 'Doe John';
}
// login user
if($id_user > 0)
{
// checks if the user is already logged
if( !isset($_SESSION['user'][$id_user]))
{
$_SESSION['user'][$id_user] = array('email'=>$email, 'name'=>$name);
}
//go to main page
$page = ROOT.'user/'.$id_user.'/index.php';
header('Location: '.$page);
exit;
}
}
index.php
https://github.com/maksa9/multiple-user-login/blob/master/index.php
Main page of the application.
<div>
<h1>Welcome: <?php echo $user_name ?> (<?php echo $user_email ?>) [<?php echo $id_user ?>]</h1>
<p>Choose an account</p>
<p>Login with the another account</p>
<p>Log out</p>
</div>
swap.php
https://github.com/maksa9/multiple-user-login/blob/master/swap.php
Allows the user to choose the account.
foreach($_SESSION['user'] as $idus => $userA)
{
echo '<p>'.$userA['name'].' ('.$userA['email'].') ['.$idus.']</p>';
}
logout.php
https://github.com/maksa9/multiple-user-login/blob/master/logout.php
Logout user. Check for active user accounts and redirects them if any.
unset($_SESSION['user'][ID_USER]);
if(count($_SESSION['user']) == 0)
unset($_SESSION['user']);
// checks for active user accounts and redirects them if any
if(isset($_SESSION['user']))
{
$sess = $_SESSION['user'];
$id_user = (int)key($sess);
if(isset($_SESSION['user'][$id_user]))
{
$page = ROOT.'user/'.$id_user.'/index.php';
header('Location: '.$page);
exit;
}
}
.htaccess
https://github.com/maksa9/multiple-user-login/blob/master/.htaccess
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^user\/([0-9]*)\/index.php$ index.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/logout.php$ logout.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/login.php$ login.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/loginform.php$ loginform.php?user=$1 [NC,L]
RewriteRule ^user\/([0-9]*)\/swap.php$ swap.php?user=$1 [NC,L]
RewriteRule ^user\/$ index.php [NC,L]
RewriteRule ^user$ index.php [NC,L]
You cant
When a cookie is created it is possible to control its visibility by setting its 'root domain'. It will then be accessible to any URL belonging to that root. For example the root could be set to "example.com" and the cookie would then be available to sites in "www.example.com" or "xyz.example.com" or "example.com". This might be used to allow related pages to 'communicate' with each other. It is not possible to set the root domain to 'top level' domains such as '.com' or '.co.uk' since this would allow widespread access to the cookie.
By default cookies are visible to all paths in their domains, but at the time of creation they can be retricted to a given subpath - for example "www.example.com/images".
so any tab which is having same root domain can access that cookie.
The session cookies are server specific AFAIK, so what you could do is set up different DNS names for the same server, e.g. subdomains like: session1.myserver.com, session2.myserver.com, session3.myserver.com
Well #dm4web's answer is kind of correct but you have to pay heed to his security warnings though. The best thing that you can do is take a bi-directional approach.
Direction One
Regular Login.
Create a Unique session ID and pass it via the URL.
Direction Two
Check Session via i) Logged In User and ii) Check Session ID via URL Param
Now, let's take an example:
$usrname: Fool
$psswd: dm4web
PHP Code
session_start();
//all inputs should be sanitized
$sql = "SELECT * FROM `users` WHERE `usrname`='".$usrname."' AND `psswd` = '".$psswd."'":
$dbh = new PDO('odbc:db', 'db2inst1', 'ibmdb2');
$count = $dbh->exec($sql);
if($count > 0){
//Guy is logged in
$a = session_id();
//**Use this $a in every URL parameter under current session**
}
else {
//Go f**k yourself >> to the user ;)
}
But you should notice that you can't directly jump into that user/pass match scheme. First you have to ensure that you find out if the user is already logged in or not. Also, based on the SESSION Cookie from PHP, you figure out that
If there is an active log in on the machine
If there is an active login on the URL [vide the $a from the session_id thing]
You match the URL parameter under all circumstances, cross reference with the SESSION cookie and proceed!
Good Luck!
Let me know if you've any more questions!

How to prevent the loss of form data when session expires?

QUESTION
Using ASP.NET VB and/or JavaScript how can a user be prevented from losing form data when a session expires?
The Problem
Currently when a user is filling out form data for a period longer than the session timeout period all form data is lost on post due to session expiry.
Client side actions such as typing DO NOT reset the session timeout period.
Ideas
I would like to know ways to prevent this problem occurring.
My initial idea is a notification message warning of pending expiry
and an option to reset session timer.
An alternate idea is a way to pass a key press or mouse movement to the server to cause an auto refresh of session timer.
SOLUTION 1 : KEEP SESSION ALIVE
On way of to solve your problem is to keep session alive while the form is opened. I'm sure there many ways to 'keep alive' user's session. For me, I use generic handler and this work fine at least in my requirement.
First, create a generic handler and enter code as below:
Public Class KeepSessionAlive
Implements IHttpHandler, IRequiresSessionState
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Session("KeepSessionAlive") = DateTime.Now
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Make sure your generic handler class implements IRequiresSessionState as above.
Then in you form page, use jQuery.post to post request the above handler at time interval of you choice. For example:
<script type="text/javascript">
$(function () {
setInterval(function () { $.post('<%= ResolveClientUrl("~/KeepSessionAlive.ashx")%>'); }, 10000); ' 10 secs interval
});
</script>
While user is on the form, the POST requests will keep refreshing user's session just like normal page requests and therefore, IIS will keep on reseting the session timeout.
SOLUTION 2 : ALERT USER BEFORE TIMEOUT
Another way is to alert user when session is about to end. This can be achieved simply by using plain javascript alone. I used this method few years back so pardon my scripting.
Create a javascript method :
function sessionTimeout(n) {
setTimeout("alertSessionTimeout()", (n - 1) * 60 * 1000);
}
function alertSessionTimeout() {
var answer = confirm("Your session is about to expire in 1 minute.\n\n
Click 'OK' to extend your session.\n
Click 'Cancel' to terminate you session immediately.");
if (answer == true)
window.location = location.href;
else {
window.top.location = 'logout.aspx';
}
}
On your form page, just enter onload script on your body tag:
<body onload="sessionTimeout(<%=session.Timeout %>)">
So, if your timeout setting is 10 minutes, user will be alerted on the 9th minute. Of course, you might want to change the code when user click OK button. My code above will refresh the page and that definitely not what you want to do, or else, user's data will be lost. You can use the generic handler as in SOLUTION 1 above to reset the session and call sessionTimeout again to reset client side timeout countdown.
In the age of single page apps if you need to work with old school approach, my advise would be to create Ajax request that constantly updates data in your website or just checks for session expiration (probably request itself would prevent that). But if it happens and you receive session expired message you could just show some login popup for user to login without leaving actual page.

am using javascript to connect user login to my website

am using a JavaScript to connect users to the homepage after the processing page have finish loading and sent the user to the homepage of welcome.html but the fact is how do i end the session after the click the log out button, because after signing out and if they hit back they will still get back the welcome.html, i have try disabling the back button in the browser but that's not awesome, i just need to kill the session so that it won't get them back to the welcome.html after they sign out instead it goes back to login page and require them to sign back in to access the welcome.html, and in this fact am not using php or DB to connect the user login, am using javascript, i don't know if it could work maybe with php simple line of codes or tags.
Here is my JavaScript code, i use to connect the users:
function Login(FORM){
var done=0;
var username=document.login.username.value;
username=username.toLowerCase();
var password=document.login.password.value;
password=password.toLowerCase();
if (username=="jonson111" && password=="happy111") { window.location="HomeAccess_uche/processing.html"; done=1;}
if (username=="wilsonqaz" && password=="open123qaz") { window.location="HomeAccess_wilson/processing.html"; done=1; }
if (done==0) { alert("USERNAME OR PASSWORD IS NOT IN THE DATABASE PLEASE TRY AGAIN!"); }
}
am using dreamweaver and yes i know i will encrypt the Java codes so that users will not understand it, but i just need to end the session after they sign out, this have given me a hard time to figure out i have search everywhere in Google but nothing, anyone can help?
what ever you wrote is all about client side code. there is no point in worry about session , because you don't have a session at all. you are just using javascript. you don't have any server side code to handle session. anybody can see the user name and password by looking at your javascript code. More over once you redirect the page by window.location="HomeAccess_wilson/processing.html"; your " done=1; " and all the javascript variable will reset.
DISCLAIMER: This is a TERRIBLE IDEA. Your site will be completely unsecure. I am ONLY explaining a way to make it work so that a completely innocent, naive user would get the intended effect. Also, this will only work in modern browsers supporting local storage.
function save_login() {
localStorage.loggedIn = true;
}
function save_logout() {
localStorage.loggedIn = false;
}
Call those functions when they log in or log out, and then on every "secure" (but not really, this is totally unsecure) page you do
if (localStorage.loggedIn == false) {
window.location.href = "yoursite.com/login" //or whatever page you
//want to send them to
}

Categories

Resources