I ran into a problem with my PHP session lately.
For developing I am using a MVC (Model View Controller) structure.
The important files:
├───classes
├───controllers
│ base_controller.php
| ...
│
├───helpers
├───parts
└───views
login_view.php
register_view.php
...
index.php
Problem: login_view.php can't "find" the $_SESSION["currentUser"], that is set in base_controller.php.
Explanation: The session is started in the index.php before the base_controller.php is loaded.
<?php
require_once("php/classes/DB.class.php");
require_once("php/classes/Functions.class.php");
require_once("php/classes/User.class.php");
session_start();
require_once("php/classes/ErrorMsg.class.php");
require_once("php/controllers/base_controller.php");
?>
The $_SESSION["currentUser"] is set in the base_controller.php after successful login. The $user object is stored in the Session. (No, not serialized, I know. But on purpose.)
if(login($username, $password)){
$m = "";
$_SESSION['currentUser'] = $user;
require_once('php/views/register_view.php');
exit();
}
The session is successfully created. Register_view.php is displayed and I am able to use the session.
When I reload the page however, and login_view.php is showed again, I can not use the session at all. Also, it seems that the base_controller.php itself can't use the session too.
The important parts of my base_controller.php:
$user = new User();
$error = new ErrorMsg();
...
//Button Login Pressed
if(isset($_POST["submit_login"])){
if(isset($_POST["login_username"]) && isset($_POST["login_password"])){
$username = htmlspecialchars($_POST["login_username"], ENT_QUOTES);
$password = $_POST["login_password"];
if(login($username, $password)){
$m = "";
$_SESSION['currentUser'] = $user;
require_once('php/views/register_view.php');
exit();
}
else{
$m = $error->WriteError("Login nicht möglich. Falsche Zugangsdaten.", "base_controller -> function login", "");
require_once('php/views/login_view.php');
exit();
}
}
}
...
//Does not work. isset($_SESSION["currentUser"]) returns FALSE
if(isset($_SESSION["currentUser"])){
if($_SESSION["currentUser"]->isLoggedIn()){
require_once('php/views/register_view.php');
exit();
}
}
// Display Login Page
require_once("php/views/login_view.php");
So to summarize it: register_view.php can use $_SESSION["currentUser"], login_view.php and base_controller.php cannot.
I've tried to
echo var_dump($_SESSION['currentUser']);
same as
echo var_dump($_SESSION[]);
but both return NULL or an empty array when used in login_view.php -> But give valid results in register_view.php
Do you have any idea what could be the cause of this non-persistent session?
I really hope I just made a very foolish mistake. You're welcome to laugh constructively. ^^
Are you calling start_session in login_view.php too?
start_session should always be called before using session variables.
Problem solved!
How I solved it:
Please make sure to read the original problem so you understand the fix.
The main problem was, that I tried to save the object $user directly into the $_SESSION. Due to the __PHP_Incomplete_Class the whole thing did not work. I fixed it with storing the User-Data in an array.
$_SESSION["currentUser"] = array("id"=>$user->GetUserId(),"firstname"=>$user->GetFirstname(),"lastname"=>$user->GetLastname(),"username"=>$user->GetUsername(),"lastlogin"=>$user->GetLastLogin(),"group"=>$user->GetGroup(), "class"=>$user->GetClass());
Now, the advantage of directly editing and using functions from the Class however, is gone. I can not use something like
foreach($_SESSION["currentUser"] as $key => $obj){
return '<p>'.$obj->getContent().'</p>';
}
anymore. Also, I can't directly set fields in the User Class anymore.
$_SESSION["currentUser"]->checkIfOnline();
However, to "log out" I just have to delete the session.
unset($_SESSION["currentUser"]); //To delete User session
Once all user-data is saved in a DB, it's perfect that way Session deleted = User logged out.
Related
I have two MySQL tables. The first one is for the user's credentials i.e. username, password, business_id (system generated). The second one has the user's profile for multiple entities e.g. business name, location, profile_id and business id (system genrated - the same number for the business_id).
The user can edit the details of their business details i.e. their details in the second table. The business id would be say 'abcdef' and profile id would be say 1234567, if they have a second business profile it would be say 1235879.
In order to edit each profile I would have to have the following URL
Edit Business Profile
For the second one it would be
Edit Business Profile
In turn when the a href is clicked the url in the browser would be edit_profile.php?id=1234567 and for the second one would be edit_profile.php?id=1235879
Would it be possible that instead of having edit_profile.php?id=1234567 and edit_profile.php?id=1235879 in the URL I would have edit_profile.php?id=1234567 and for the second one would be edit_profile.php
I don't want the User to see the id i.e. have only edit_profile.php
Ideally, I would like to use a PHP solution, please.
Yes, it is possible, but not exactly what are you trying to do
Solution #1
Intoduction
First of all, it should work only on users who are currently logged in and are trying to see their profile. The final results to reach is to not display ID in URL if ID is equal to current logged user's ID. It is more common than Solution #2 but if you want to hide all IDs, skip this solution.
Pluses:
There is not too much to change, just add a few more lines for checking current user ID
You can still use <a></a> tags for Edit Business Profile links.
Minuses:
Only current logged user's ID will be hidden in the URL
So what to do...
You probably use sessions to let users remain logged in even if they refreshed the page. You are on the right path, but you should add at least one more element to $_SESSION (Profile identification, so we can call it as profile_id for example).
Assume you are using this login formula:
function check_login($username, $password)
{
// query to find user with these inputs (encrypted password, prepared statements, etc)
if($query->num_rows > 0) // user exists
{
// fetch your query
// ...
session_start();
// set the session probably user is logged
// some return on success (probably redirect)
}
else
{
// some return on false
}
}
Now you should add one more $_SESSION element to save your current profile_id value:
session_start();
// ...
$_SESSION['profile_id'] = $result->profile_id; // <--- THIS IMPLEMENT
// some return on success (probably redirect)
1/2 is done!
Half of the problem is already finished, now all you need to do is compare $_GET input with $_SESSION.
Again, assuming your edit_profile.php file looks like this:
if(isset($_GET['id']) && !empty(trim($_GET['id'])))
{
$profile_id = intval($_GET['id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
So now instead of error profile id is not defined we can assign to $profile_id variable index profile_id of superglobal $_SESSION:
else
{
$profile_id = intval($_SESSION['profile_id']);
}
Notice that I am assuming you have condition to reject access to this script, if user is not logged (some condition at the start).
Now your code should work but maybe you are asking the question what if user knows his ID and types it into URL?
So you have two choices:
Let it be as it is
Add condition to check if $_GET['id'] equals to $_SESSION['profile_id'] then redirect to edit_profile.php
Final thoughts...
Maybe if you are generating the list of the users, where the user can edit the others' users profiles including himself's, you want to remove id parameter of the edit_profile.php URL if the user's ID is equal to current ID in fetch loop. You can inspire by this simple function:
function generate_profile_edit_url($id)
{
session_start(); // for the case, you don't have started session yet
return 'Edit Business Profile';
}
Just in every fetch iteration you will use this function, like in the example below:
// ...
echo generate_profile_edit_url($result->profile_id);
// ...
Solution #2
Introduction
This solution will reach to the editing user's profile without any ID parameter in URL. It is designed for situation where user has rights to edit someone else's profile (for example, a moderator or an admin) and you still don't want to have the users' ID in the URL.
Pluses:
No ID parameter in URL needed for all users
Minuses:
you have to change every profile link to little form using POST action without JavaScript knowledge
no more <a></a> links for profile edit, again without JavaScript knowledge
users are still able to get their id if they want to
So what to do...
Firstly, we need to change edit_profile.php file. We have to recieve $_POST data containing target's profile_id.
Like in Solution #1, assume your edit_profile.php looks like:
if(isSet($_GET['id']) && !empty(trim($_GET['id'])))
{
$profile_id = intval($_GET['id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
Most of the changes will be just replacing $_GET with $_POST:
if(isSet($_POST['profile_id']) && !empty(trim($_POST['profile_id'])))
{
$profile_id = intval($_POST['profile_id']);
// ...
}
else
{
// probably an error profile id is not defined
}
// rest of the code ...
For this file, it is enough.
Now there is some more work to do if you have a placed profile links in different files. But we can make it easier using one simple function like this:
function get_profile_edit_button($profile_id)
{
$html = '<form action="edit_profile" method="POST">';
$html .= '<input type="hidden" name="profile_id" value="' . intval($profile_id) . '">';
$html .= '<input type="submit" value="Edit Business profile">';
$html .= '</form>';
return $html;
}
The last thing is replace current edit profile links with this function. For example you have fetch loop of users:
// ...
echo 'Edit Business Profile';
// ...
So you will replace this string with your function get_profile_edit_button():
// ...
echo get_profile_edit_button($result->profile_id);
// ...
Final thoughts...
As I mentioned in minuses, profiles' ids cannot be totally hidden. If someone opened Source code of your page, he can see profile_id in hidden form type:
<input type="hidden" name="profile_id" value="1234567">
It is only on you what solution you prefer, but I can recommend you Solution #1. There is nothing bad about having IDs in URL. Stack Overflow has it too as you can see it on questions, answers, comments and users.
Useful resources:
PHP Session Security
PHP form token usage and handling
When logging in, try saving the user ID and business ID inside session.
As for example..
$logged_in = some_logic_stuffs();
if($logged_in){
session_start();
$_SESSION['user_id'] = SOME_ID_FETCHED_FROM_LOGIN_LOGIC;
$_SESSION['business_id'] = SOME_ID_FETCHED_FROM_LOGIN_LOGIC;
}
Now, when user goes to edit_profile.php, do
session_start();
$business_id = $_SESSION['business_id'];
$user_id = $_SESSION['business_id'];
For the login logic, try reading this tutorial:
http://www.formget.com/login-form-in-php/
If the user can edit multiple business profiles, the $_SESSION solutions would not work. You would need to disguise what gets sent to the address bar:
You would need to change your code to POST the data rather than sending it as a GET request.
To do this you could either use JavaScript to fake a form post on the link click, or wrap your link in a form tag and set method="POST".
POST sends the data "behind the scenes" rather than exposing it in the browser. I should add that this would still be visible to anyone wanting to discover your IDs, but it would hide it from the casual user at least.
If you really wanted security, #BobBrown's suggestion to tokenise would be a great way forward. You may find, however, that just hiding the ID from display on-screen is enough. Just make sure your user management system will restrict who can edit a particular business.
Try this
<?php
session_start();
include('dbconnect.php');
if(isset($_SESSION['username']))
{
$username = $_SESSION['username'];
$userid = $_SESSION['id'];
}
else
{
$_SESSION['id'] = "";
$_SESSION['username'] = "";
}
if($username <> "")
{
$username = 'username';
$userid = 'id';
}
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 900))
{
// last request was more than 30 minutes ago
session_unset(); // unset $_SESSION variable for the run-time
session_destroy(); // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
?>
then
<?php
#if the form is set (meaning that the information was submitted then define what the parameters are for each
if(isset($_REQUEST['username']) == TRUE)
{
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
#make sure there are no blank fields
if($username == "" OR $password == "")
{
echo '<p class="text-danger">Please enter a Username and Password</p>';
}
else
{
$userid = finduser($username, $password);
if($userid > 0)
{
loginuser($userid);
}
else
{
echo '<p class="lead text-danger">The Username and/or Password enter is incorrect</p><br />';
}
}
}
?>
after that then this
<?php
if(isset($_SESSION['username']))
{
if($_SESSION['username'] <> "")
{
//do something
}
else{
//form or something else
?>
<form>form goes here</form>
<p> or something else you want</p>
<?php
}
}
?>
Start your PHP with session_start(); then when the user logs in make a session value for the ID:
$_SESSION['profile-id'] = 1235879; //Select it from database
after in your edit_profile.php do that:
if (!isset($id)) {
$id = $_SESSION['profile-id'];
}
And then edit the $id.
Store the id in session on the first page:
$_SESSION['id'] = 12345;
And on edit_profile.php you can get the value by:
$id = $_SESSION['id'];
And start the session on every page by session_start();
Easiest and simplest way to handle your situation if you want to use Id or any information in URL and pass it through URL
then you can have a scret combination with your values like below
Firt you have to encode the value with your secret stuff for example
$sshhh="ITSMY_SECRET_VALUECODE";
$encrypted_id = base64_encode($your_value . $sshhh);
Then pass it (encrpyted_id) in URL
for example href="all-jvouchers.php?id=<?= $encrypted_id; ?>
and while getting value use below code to get back your value
$sshhh="ITSMY_SECRET_VALUECODE";
$decrypted_id_raw = base64_decode($_GET['id']);
$decrypted_id = preg_replace(sprintf('/%s/', $sshhh), '', $decrypted_id_raw);
Use $decrypted_id wherever and however you want to securely
This is for an assignment, however ive done a lot on my part to research but i feel like ive reached a wall. I need to create a page where the user can go to sign in (login.php), once they're signed in they're redirected to the index page. The link they clicked to login should be replaced with a logout link.
however with all this noted, first things first i do get into the session part and ive echoed the variables and retrieved them however it doesnt do the redirect to the index.php also when i manually click to the index.php after logging the session variables are empty. what am i doing wrong here???
so this is my php code in the login.php
$found = false;
//read the read.txt until the end of file
while(!feof($inputFile) && $found == false)
{
$line = fgets($inputFile);
// replace the special charater within the lines by there proper entity code
$lineArray = preg_split("/\,/", (string)$line);
if(strcmp($_REQUEST['email'],$lineArray[2]) && strcmp($_REQUEST['pwd'],$lineArray[4]))
{
$found = true;
echo "<script>alert(' FOUND!')</script>";
session_start();
$myuseremail=$_REQUEST['email'];
$mypassword= $_REQUEST['pwd'];
$_SESSION['login_email']=$myuseremail;
$_SESSION['login_pwd']=$mypassword;
setcookie("login_email", $_SESSION['login_email'], time()+60*60*24);
setcookie("login_pwd", $_SESSION['login_pwd'], time()+60*60*24);
header('Location:index.php');
}
}
fclose($inputFile);
and then in my index.php i contain this code before the body of my html
<?php
session_start();
if(isset($_SESSION['login_email']) && isset($_SESSION['login_pwd']))
{
$user_check=true;
echo $_SESSION['login_email'];
}
else
{
$user_check=false;
}
?>
within the index.php i also have this code lined in for my links
<li>Home</li>
<li>Register</li>
<?php
if ($user_check){
print "<li><a href='logout.php'>Logout</a></li>";
}
else{
print "<li><a href='login.php'>Login</a></li>";
}
?>
<li> Link 4</li>
I found some errors in your code, all coming down to the same point: You cannot send any custom headers after you have began outputting other data.
Where have you done this?
Here:
echo "<script>alert(' FOUND!')</script>";
session_start();//session_start() sends a cookie to the clients machine.
//How are cookies sent to clients browsers? Through headers.
And here:
setcookie("login_email", $_SESSION['login_email'], time()+60*60*24);
setcookie("login_pwd", $_SESSION['login_pwd'], time()+60*60*24);
header('Location:index.php');
Personally, I think your code is a complete mess. Because I have nothing better to do, I'll re-write it for you, explaining each step as I go along.
Let's begin:
So the first thing you want to work on is your text file, which stores all the user details.
Instead of using plain lines or whatever, we should use JSON to split users details, from user to user.
So here's what the text file will look like with two users in it:
{"navnav":{"username":"navnav","pass":"deb1536f480475f7d593219aa1afd74c"},"user2":{"username":"user2","pass":"deb1536f480475f7d593219aa1afd74c"}}
Notice how I've also used the username as keys too and how I've hashed the password. So we call this file user.txt and store it somewhere safe.
Now, for the login page, we shall simply get the data through the POST method, compare it, set sessions and tell the user to go somewhere else (redirect them).
session_start();//need to start our session first, of course
//check if any login data has been posted our way
if ( isset($_POST['login']) && !empty($_POST['username']) && !empty($_POST['password']) )
{
//assign input data to temp vars
$username = $_POST['username'];
$password = md5($_POST['password']);//notice how I hash the password
// get the data fro the text file
$userData = file_get_contents('path to your text file');
//decode the json data to an assoc array
$userData = json_decode( $userData , true );
//check if the user exists
if ( array_key_exists( $username , $userData ) === false )
{
echo 'the username '.$username.' is invalid.';//notify the user
exit();//bye bye
}//end of user does not exist
//so now we know the user name exists (because we've got to this line)
//we shall compare with the password
if ( $userData['$username']['password'] !== $password )
{
echo 'Your password is incorrect';//notify the user
exit();//bye bye
}//end of incorrect password
else
{
//time to set sessions and stuff
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
//send the redirect header
header('Location: index.php');
exit();
}//end of password is correct
}//end of login data has been sent
That's all your login code, but you need your html form setup correctly for the right things to be posted with the right names. So use this html form:
<form action="login.php" method="post" name="login" target="_self" id="login">
<p>
<label for="username">Username</label>
<input type="text" name="username" id="username" />
</p>
<p>
<label for="password">Password</label>
<input type="text" name="password" id="password" />
</p>
</form>
That's your login page completely sorted.
Now for your index.php:
As you did before, check if the user is logged in and throw the status is in a var:
session_start();//resume your session (if there is one) or start a new one
//set default user status
$userStatus = false;
if ( isset($_SESSION['username']) && isset($_SESSION['password']) )
{
$userStatus = true;
}//end of user is logged in
For your HTML login/logout:
<li>Home</li>
<li>Register</li>
<?php
if ($userStatus === true){
echo "<li><a href='logout.php'>Logout</a></li>";
}
else{
echo "<li><a href='login.php'>Login</a></li>";
}
?>
<li> Link 4</li>
And there you have it.
Let me know if you have any problems.
One more thing:
This is far from secure. Why? You're using text files, you're using text files and you're using text files.
EDIT:
To separate the JSON data by user, simply edit the text file manually (see my comment).
Or you could just paste this into your text file:
{"navnav":{"username":"navnav","pass":"deb1536f480475f7d593219aa1afd74c"},
"user2":{"username":"user2","pass":"deb1536f480475f7d593219aa1afd74c"}}
Do you see how there is no \n in the above? Because I just created a new line manually (by just hitting enter). \n will make the JSON code invalid, so that's why you should avoid it. This method just means if you have to create new users, and you need a new line for each user, then you will have to do it manually.
Actually your script does the opposite of what you are probably intended to:
strcmp does compare both parameters, but it does not return a boolean value.
First thing to do 'd be to change that line to:
if ($_REQUEST['email'] === $lineArray[2] && $_REQUEST['pwd'] === $lineArray[4]) {
First of all, never send a header after some output has occurred, i.e. when you do echo "<script>alert(' FOUND!')</script>"; this is considered output and a header will be generated by PHP and your header line later on will be ignored.
Try using header without any output being sent first, this should fix the redirect problem.
As far as why the session information is wiped, try the following line on the redirect:
header('Location:index.php?'.SID);
It shouldn't be required but its worth giving it a shot.
I'm aware that this topic has been covered before here on Stack, and I have looked at some answers, but I'm still a bit stuck, being fairly new to PHP. Every page on my website requires a login, and so users are redirected to a login page on page load. At the top of each page then I have:
<?
require("log.php");
include_once("config.php");
include_once("functions.php");
?>
This redirects the user to log.php (with new code added):
<?
session_name("MyLogin");
session_start();
if(isset($_SESSION['url']))
$url = $_SESSION['url']; // holds url for last page visited.
else
$url = "index.php"; // default page for
if($_GET['action'] == "login") {
$conn = mysql_connect("localhost","",""); // your MySQL connection data
$db = mysql_select_db(""); //put your database name in here
$name = $_POST['user'];
$q_user = mysql_query("SELECT * FROM users WHERE login='$name'");
if (!$q_user) {
die(mysql_error());
}
if(mysql_num_rows($q_user) == 1) {
$query = mysql_query("SELECT * FROM users WHERE login='$name'");
$data = mysql_fetch_array($query);
if($_POST['pwd'] == $data['password']) {
$_SESSION["name"] = $name;
header("Location: http://monthlymixup.com/$url"); // success page. put the URL you want
exit;
} else {
header("Location: login.php?login=failed&cause=".urlencode('Wrong Password'));
exit;
}
} else {
header("Location: login.php?login=failed&cause=".urlencode('Invalid User'));
exit;
}
}
// if the session is not registered
if(session_is_registered("name") == false) {
header("Location: login.php");
}
?>
The login form is contained in login.php. The code for login.pho relevant to the PHP/log.php is:
<?
session_start();
if($_GET['login'] == "failed") {
print $_GET['cause'];
}
?>
and
<form name="login_form" id="form" method="post" action="log.php?action=login">
The answer that I came across stated that I should add:
session_start(); // starts the session
$_SESSION['url'] = $_SERVER['REQUEST_URI'];
to the top of each page, which I did, at the top of the page (above "require("log.php");"), and then add:
if(isset($_SESSION['url']))
$url = $_SESSION['url']; // holds url for last page visited.
else
$url = "index.php"; // default page for
to my login page, and use the following URL for redirect on successful login:
header("Location: http://example.com/$url"); // perform correct redirect.
I am not 100% where the code which stores the referring URL should go, at the top of log.php or login.php.
I have tried adding it to both, but the login page is just looping once I have entered the username and password.
I wonder if someone could help me get this working?
Thanks,
Nick
It appears that I don't have the privilege to comment on your post, so I'll do the best that I can to answer. I apologize for all of the scenarios, I'm just doing the best I can to answer on a whim.
SCENARIO 1:
If you've truly not selected a database in your code, as demonstrated here, could that potentially be your issue? Please do note, that the code below, is the code you've posted.
$db = mysql_select_db(""); //put your database name in here
SCENARIO 2:
The code below is not something I've ever used in anything I've built, might I suggest that you try replacing that line of code with the line below it?
if(session_is_registered("name") == false) { // Current
if(isset($_SESSION['name']) == false) { // Potential Replacement
SCENARIO 3:
If you're logic for the following, exists on the login.php file as well... That could potentially be your problem. Upon visiting your site, I noticed your form appears on login.php, yet your logic is posting to log.php. I'm hoping this bit of code can help rule out that "jump", as login.php might be saving itself and overwriting the $_SESSION variable you've established
session_start(); // starts the session
$_SESSION['url'] = $_SERVER['REQUEST_URI'];
If it's too complex to take it out of the login.php file, if you even have it there, I've put together some code that you can use to create "internal" breadcrumbs, so you can go 2 pages back in your history.
if(!isset($_SESSION['internal_breadcrumbs']))
$_SESSION['internal_breadcrumbs'] = array();
$_SESSION['internal_breadcrumbs'][] = $_SERVER['REQUEST_URI'];
$max_breadcrumbs = 5;
while(count($_SESSION['internal_breadcrumbs']) > $max_breadcrumbs)
array_shift($_SESSION['internal_breadcrumbs']);
That will create an array with a max of $max_breadcrumbs elements, with your most recent page at the end, like the following
Array
(
[internal_breadcrumbs] => Array
(
[0] => /other_page.php
[1] => /other_page.php
[2] => /other_page.php
[3] => /user_page.php <-- desired page
[4] => /login.php <-- most recent page
)
)
So now... you can setup your url to be something more like the following...
// I'm doing - 2 to accommodate for zero indexing, to get 1 from the current page
if(isset($_SESSION['internal_breadcrumbs']))
$url = $_SESSION['internal_breadcrumbs'][count($_SESSION['internal_breadcrumbs']) - 2];
else
$url = "index.php"; // default page for
All the best, and I certainly hope this has helped in some way.
IN SCENARIO 4
From the client test the login/password which ajax XMLHttpRequest with javascript code to a dedicated script for validation (do it on mode https for secure)
If response is right send the login password to your script server.
Stips : Encoding password is better secure !
Using header() function it's a bad idea.
Manual specification say ;
Remember that header() must be called before any actual output is
sent, either by normal HTML tags, blank lines in a file, or from PHP.
It is a very common error to read code with include, or require,
functions, or another file access function, and have spaces or empty
lines that are output before header() is called. The same problem
exists when using a single PHP/HTML file.
So in your case, i suggest that to use cookies with an ID generate only for the session, at the first connection its generate, and the duration of the cookie maybe for only from 2 to 10 minutes.
Regenerate cookie each time the loging.PHP is called !
Have a nice day
I am setting up a login form.
Expected Result:
Echo session username on page after successful login.
Actual Result:
Login is successful. Session username does not echo. Appears as though session username either does not exist or it is not persisting to the next page.
Is there something wrong with the code below?
LOGIN.PHP
...
session_start();
if (mysql_num_rows($result) ==1)
{
session_regenerate_id();
$row = mysql_fetch_assoc($result);
$profileid = $row['userid'];
$profile = $row['username'];
//Set session
$_SESSION['profileid'] = $profileid;
//Put name in session
$_SESSION['profile'] = $profile;
//Close session writing
session_write_close();
//Redirect to user's page
header("location: index.php?msg=userpage");
exit();
}
...
INDEX.PHP
...
<?php
session_start();
if($_GET['msg']=="userpage")
{
echo $_SESSION['profile'];
}
...
Edited:
Put session_start in php tags.
Changed HTML to INDEX.PHP.
"If" brace closed.
Changed while to if in LOGIN.PHP.
Changed username to userpage
You don't need to be opening/closing sessions, it's not worth the extra lines of code. I also don't know why you're regenerating the session ID.
But, one thing is your HTML file is badly constructed, and it almost looks like the session_start() isn't inside any PHP tags, so it's not even being treated as code.
first of all your HTML is yet PHP as it involves PHP tags only.
Replace while with if coz you only want to set the $_SESSION variables once.
And for the last part what you are looking for is this
<?php
session_start(); //at the beginning of your script
if($_GET['msg']=="username")
{
echo $_SESSION['profile'];
}
?>
Make sure you eliminate all the whitespaces before the opening of your first <?php tag on your script as that gives potential header errors.
close the if loop in html file
EDITED:
I did this simple code in my page and as per session concept is concerened The code is working fine...make corrections accordingly
p1.php
<?php
session_start();
//Put name in session
$_SESSION['profile'] = "Pranav";
//Close session writing
//Redirect to user's page
header("location: p2.php?msg=userpage");
exit();
?>
p2.php
<?php
session_start();
if($_GET['msg']=="userpage")
{
echo $_SESSION['profile'];
}
?>
FOR NEW SESSION ID
USE THIS
$a = session_id();
I have a web server with Magento 1.4.0.1 installed. I have another web site that shares credential with it. I've managed to check if the customer is logged in or not (after having changed the cookies location in Magento), but things got complicated when I also tried to figure out if an admin was logged in. I can only get the proper answer for the first session I asked for (either the customer OR the admin, the second one is NEVER logged in).
How can I have both answers?
Here is the code I'm using to test that out:
require_once '../app/Mage.php';
umask(0) ;
Mage::app();
// Checking for customer session
Mage::getSingleton('core/session', array('name'=>'frontend') );
$session=Mage::getSingleton('customer/session', array('name'=>'frontend') );
if ($session->isLoggedIn()) {
echo "Customer is logged in";
} else {
echo "Customer is not logged in";
}
// Checking for admin session
Mage::getSingleton('core/session', array('name'=>'adminhtml') );
$adminsession = Mage::getSingleton('admin/session', array('name'=>'adminhtml'));
if($adminsession->isLoggedIn()) {
echo "Admin Logged in";
} else {
echo "Admin NOT logged in";
}
So with the code like this, the admin is never logged in. If you put the part about the admin first, then the customer is never logged in. It seems like I'm missing a line between the two requests.
This may be the same problem than this unanswered question: Magento how to check if admin is logged in within a module controller
This seems like a popular problem, but I could not find the proper solution...
Thanks for your help!
I've found that "bug-feature" from another angle of view (trying to login customer from adminside), but still found the cause.
The problem is with session_name() function. If you go to Mage_Core_Model_Session_Abstract_Varien you'll see there that the session object is using standart PHP session functions and PHP can't handle two sessions at the same time.
You session id for adminside is stored in cookie adminhtml, while for clientside your session id is in frontend cookie. Then in adminside you have session ID initialized by adminhtml cookie. When in adminside, your customer/session object is stored inside something like $_SESSION['customer'] (haven't checked exact key) inside PHP session for ID stored in adminhtml cookie. This means that customer/session object is refering to different sessions when inside admin and client parts of magento.
What you need to do is switch the session data. You can do this with the following code:
$switchSessionName = 'adminhtml';
$currentSessionId = Mage::getSingleton('core/session')->getSessionId();
$currentSessionName = Mage::getSingleton('core/session')->getSessionName();
if ($currentSessionId && $currentSessionName && isset($_COOKIE[$currentSessionName])) {
$switchSessionId = $_COOKIE[$switchSessionName];
$this->_switchSession($switchSessionName, $switchSessionId);
$whateverData = Mage::getModel('mymodule/session')->getWhateverData();
$this->_switchSession($currentSessionName, $currentSessionId);
}
protected function _switchSession($namespace, $id = null) {
session_write_close();
$GLOBALS['_SESSION'] = null;
$session = Mage::getSingleton('core/session');
if ($id) {
$session->setSessionId($id);
}
$session->start($namespace);
}
Here is what I use..
Mage::getSingleton('core/session', array('name'=>'adminhtml'));
$session = Mage::getSingleton('admin/session');;
if (!$session->getUser())
{
die("You aren't an admin!");
}
It is quite simple but not a recommended solution. I myself spend number of hours to do this.
For, windows based server try below solution:
$sessionFilePath = Mage::getBaseDir('session').DS.'sess_'.$_COOKIE['adminhtml'];
$sessionFile = file_get_contents($sessionFilePath);
$exp_cookie = explode(';',$sessionFile);
if(count($exp_cookie) > 100)
{
return "login";
}
return "expire";
For, Linux based server try below solution:
$sessionFilePath = Mage::getBaseDir('session').DS.'sess_'.$_COOKIE['adminhtml'];
$sessionFile = file_get_contents($sessionFilePath);
$exp_cookie = explode('--',$sessionFile)
if(count($exp_cookie) > 10)
{
return "login";
}
return "expire";
Thanks,
Kashif
Here is a simple script to check admin is logged or not and if logged get admin details of Magento.You can call to the session and the call to user function to get all details.
$userDetails = Mage::getSingleton('admin/session'); // Get data from the session
$userID = $userDetails->getUser()->getUserId(); // Get user ID
$userID = $userDetails->getUser()->getEmail(); // Get user Email
Please refer to http://webexplorar.com/magento-admin-details/ for more details.