I have a webapp that uses login/logouts so I have session management. Basically every page so far starts with
session_start();
if(!isset($_SESSION['username'])) {header("Location: index.php");} else { rest of the page's functionality}
I am now creating a class (User.php); that will be accessed by another .php page. Do I need to implement the above for security, and if so how? Should I put classes above the webroot?
Thanks
first of all, although i assume you've thought of this; just to check if the username is set in a session is not particularly save. If you want to check if a user is logged in some additional tests should be present.
than back to your question; a page could possibly access the User class even if no logged in user exists (eg. when you want to display this particular users' public comments on a blog post). So no, your test would not be needed. Furthermore you could also build in a check if the user is logged in into the User class (or better still; the Authentication class you'll build around it), so you could do something like:
if(Authentication::is_logged_in($_SESSION['username']) === true) {
echo 'yeeehaaaa! You\'re logged in bro!';
} else {
echo 'what are you doing here?! Get lost! (or log in)';
}
Related
I'm fairly new to PHP an was wondering how I have to make the user login before they can go to any other page on the website.
For example on www.cyka.us/p/index.php it will redirect them to www.cyka.us/p/login.php
Have you ever used sessions in php? You can use sessions as a marker if a certain user is logged in or not. It can be implemented like this:
$isLogIn = $session('login');
if($isLogIn){
//go to other webpages
}
Search sessions for further information :)
You simply test for it:
if (!user_is_logged_in()) {
http_response_code(403);
include("p/login.php");
exit;
}
… the specifics of the user_is_logged_in function will depend on how you've implemented your login system.
You can do this with sessions concept in php. For every page you need check whether the user is logged in or not and redirect to (login)desired page.
When the user decides to sign out, they obviously do so by using a "Sign out" button.
When they do, this script is executed:
if(isset($_POST['submit_Logout'])){
$_SESSION['backend']->logout(); // see this function bellow
unset($_SESSION['user']); // unset only this session since there are other sessions I'd like to keep
session_regenerate_id(true); // makes sure the session id is updated, and the old one is discarded
KD::notice('success',$success_LoggedOut); // adding a notice to another session
KD::redirect('/'); // redirecting the user using header();
session_commit();
}
I'm just unsetting this particular session (user) since there's other sessions that keeps other data available, regardless if the user is logged in or not, to better the user experience.
The logout()-function looks like this - for now:
public function logout(){
$this->accessible=false; // just a flag to check against (see bellow)
$this->username=''; // empty the username
}
Since I'm unsetting the session that holds the related user data, I just realized that this function is probably unnecessary. Alternatively move the unset part etc. into the function..
Anyway, I've come to experience that when a user has logged out, he/she, or somebody else for that matter, has the opportunity to just hit the backwards button in their browser, and voila, they can view the page(s). Of course, if they start clicking on any links, they gets thrown out. But the back-button is still available..
I believe this happens as a result of cached pages/views by the browser. So when they click the back-button, they see a cached page/view stored in the browser memory or something..
Since this page, or view, is loaded into my template trough a index.php page with a permanent <head>, there's not much I can do about the caching of these restricted pages/views. Or is there?
Deleting records from the browsers history is not possible? or preventing these pages from being recorded in the first place?
Point is. What I need to do, i believe, is to force the browser to always request the page from the server. So regardless if the user hits the back-button, or a link to a restricted page, the page should always reqest it from the server, and not the browsers memory..
Or am I not getting this correct?
If so. I do wonder how. How is this usually done?
I have this in my class
private $accessible = false; // when logged in, this is set to true
public function accessible(){
return $this->accessible;
}
At the very top of the page that includes the views into the restricted area I have this:
if($_SESSION['user']->accessible()===true):
Othervise the user is prompted with a login screen.
But that doesn't work as expected. This check is not performed when the user uses the back-button in their browser...
Thanks in advance..
UPDATE
Heres a quick overview of my structure/layout:
/*
when the user is logged in/out, the script that does that is executed up here.
That includes setting the sessions etc. aswell - which means, if the user is not logged in, the access will be set to false.
*/
<head>
</head>
<body>
/*
Here I include different pages with php include;
These pages can be home.pg.php, contact.pg.php, and of course restricted.pg.php
each of these pages includes different content (views as I like to call them) that is presented to the user based on their interaction.
Now. When the user tries to access the restricted.pg.php, I have this at the top:
*/
if($_SESSION['user']->accessible()===true):
/* now each view that is included here should be not accessable if accessable() is not true. */
else:
/* the user is presented with a login form */
endif;
</body>
Did this help?
All the pages that require some to login should have something like this,
session_start();
if(!isset($_SESSION['user']){
//REDIRECT USER TO LOGIN PAGE
}
If its because of the browser caching issue that hitting back is taking you back to cached version of the page (even though user is logged out) then you should redirect the user twice (good practice).
what I mean is create a file called logout.php so when user clicks on logout button,it redirect the user to logout.php (that'll have the session unset code) and after that redirect user to login page.
so current page ----redirects to---> logout.php ----redirects to----> login.php
i think in every page you can just check whether a session is set or not. ex. Session::handlelogin('user')
then you can just make a function namely handlelogin in Session class
Class Session {
function handlelogin($user) {
if (!isset($user)) {
//redirect the user to your login page
}
}
}
Notice: just set this up in top of the page if your using MVC architecture then you can set it up in the Controller
Session::handlelogin('user')
I'm developing a website, where in most of pages user need to log in to view pages of website. What is the best way to check if user is logged in or not, and if not redirect it to log-in page.
currently I'm using following code to do that.
if(!isset($_SESSION["username"])) //I set the session when user log in and destroy when user logout
header("location: login.php");
There are lot of pages and I put this code in every page. It also works well.
I want to know is there any other batter way to do this? Or what I'm doing is good way? and I don't need to change anything.
Simple Solution is create a file named as session.php
include your session checking code into that. Like,
if(!isset($_SESSION['YOUR_VAR'])) {
header('Location: login.php');
}
include this file into all your pages, with include OR require
I prefer require function. example in your home.php file at the beginning of page write,
<?php
session_start(); //don't forget to do this
require('session.php');
?>
NOTE : In future if you enhance your session checking code you just
have to change one file.
I usually just set a session like this once the user logs in:
$_SESSION['loggedIn'] = TRUE;
Then just check if TRUE or FALSE when needed.
ex:
if($_SESSION['loggedIn']){
//Something here
} else{
//Don't do it
}
It is depend on you architecture. If you are using any framework, like symfony you don't need to handle these for each and every page. I guess you are using pure PHP without any framework support. So you need to check whether the user is authenticated for each and every request by your own. I suggest you to without placing code segment related to logout in every page, just place it in a global function and call it in your every page. So that, if you want any simple change in that code segment, you can achieve it only changing that global function
I need to create a session on index page
if user already login in, it will header to member page.
if user destroy session, it will stay at index(login page)
what i did is
if(session_start){
header("location:member.php") or die();
}
if(isset($_POST['email']) && isset($_POST['password'])){
$email=strtolower($_POST['email']);
$password=md5($_POST['password']);
if($email && $password){
$connect=mysql_connect("localhost", "root", "");
$database=mysql_select_db("phplogin", $connect);
$SQL=mysql_query("SELECT * FROM users WHERE email='$email'");
$numrows=mysql_num_rows($SQL);
if($numrows!=0){
while($result=mysql_fetch_assoc($SQL)){
$db_email=$result['email'];
$db_password=$result['password'];
$db_firstname=$result['firstname'];
$db_lastname=$result['lastname'];
}
}
else{
die("Can't find the user");
}
if($email==$db_email && $password==$db_password){
session_start();
$_SESSION['firstname']=$db_firstname;
$_SESSION['lastname']=$db_lastname;
header("location:member.php");
}
else{
die("wrong username or password");
}
}
else{die("Please enter email or password");}
}
This works when user haven't destroy session, but when user destroy session
it didn't stay at index page
I need something like facebook, yet I don't know how facebook can share same the domain name on login page and user page.
so everytime i type facebook.com i will go to my user page, if i logout, it will become login page
You have used if(session_start). session_start() is a function. And it is used on each and every page. So it will redirect you everytime.
Another thing, you need to session_start() on the page you are storing the session and the page you are getting session values.
Instead of:
if(session_start){
header("location:member.php") or die();
}
Use:
session_start();
if(isset($_SESSION['firstname']) && isset($_SESSION['lastname'])){
header('location:member.php');
}
//and REMOVE session_start(); from where you have written.
How about on top of your page
if(!isset($_SESSION['firstname']) || !isset($_SESSION['lastname'])){
header("location:index.php") or die();
}
First of all; only checking if a session exists isn't enough if you want to check if your user is logged in (the session could exist all the same, even if the user isn't logged in). So you should write a is_logged_in() function (or something like that) first to properly check the logged in status.
The reason why your user is always redirected is because the function session_start() returns true if a session is started succesfully; if the session is destroyed, it just starts a new one. So basically it will return true pretty much always, if everything works correctly (like user has not turned cookies off etc.).
If you have written that function it's actually quite simple. Let's pretend you have two files: home.php and member.php. The first one is your homepage (with a "Hello visitor!" message and the login form), the second is the member page. If both files are 'standalone' scripts you can indeed header the user to the specific page (header('Location: home.php'); if user should login first, header('Location: member.php'); if user is already logged in).
But! If you want to 'cloak' the pages (pretty much like facebook does it), you can just include the files in your index.php. Do something like this:
if(is_logged_in()) {
require_once('member.php'); // present member profile page
} else {
require_once('home.php'); // present login page
}
In your index.php you can set a constant (see also the php manual about constants) to be sure the files can only be included from within index.php:
--- index.php:
define('VALID_INCLUDE', true);
// the rest of your code
--- home.php & member.php:
if(!defined('VALID_INCLUDE')) die('You should not request this page directly');
But please note that if you want to write applications like this, a framework could help you a lot; it covers a lot if this kind of problems and makes coding a lot faster (most frameworks come with a authentication modules of some sort, and allow you to use 'views' to present your user with the proper pages, like I have done above with the require_once solution).
I'm new to web programing and im trying to find a few good examples / tutorials on how to do a decent job of creating a website that requires users to log on to view any pages beyond the main log in page.
so far i've found 1 or 2 that ive tried but i keep running into the same problem. If i just enter the url of the page i want to see manually i can get in like there was nothing there.
Okay, I'll explain how the basic concept goes and a very simple implementation to get things going.
PHP (and most web applications) rely on RESTful services -- which, to our concern at the moment, means every request is not remotely bound to any other request being made - either that being by the same user or others.
So what does that mean?
This means that for every single request, you need to do your checks. You need to make sure if the user has permissions to execute that page, or less severely even see its contents.
How is this achieved?
By many ways, actually. There are lots of techniques used to enforce authorization on web applications but they would essentially both break down to one of two -- either centralized, or decentralized.
-- Centralized
This means all your actions (and controllers) are being handled through a single file. Say index.php. This file would then include or delegate its tasks to other files (that are not runnable on their own via normal requests) based on request parameters. This is a very popular approach, but not exactly straight forward for new developers. Examples of applications that use this approach would have URLS of the type: index.php?do=register, index.php?do=login, index.php?do=showtopic&topic_id=2, and so forth.
A simple implementation of this technique would go like:
<?php
// index.php
define('RUNNING_APP', true);
// 1. place your auth code here, or...
switch ($_REQUEST['do']) {
case 'register':
// 2. or here
include 'inc/register.php';
break;
case 'do_register':
// 2. and here, and before every include.. and so forth.
include 'inc/do_register.php';
break;
}
?>
<?php
// inc/register.php
defined('RUNNING_APP') or die('Cannot access this script directly'); // make sure to break direct access
?>
<form action="index.php?do=do_register">
<!-- form elements -->
</form>
and so forth.
I've documented where the usual auth code should go.
-- Decentralized
Using this approach, however, your auth code should go at the beginning of every single file. URLS of applications of this sort usually look something like: register.php, login.php, and so forth. The main problem here is that you need to perform all auth logic per file, as stated above, and that may be a hectic job if your files increase in amount. A convenient solution is to have that logic in a single file, and include that file (which would kill the request for unauth personel) before any of your logic. A simple example would be:
<?php
// index.php
include('inc/auth.php');
// index logic
?>
<?php
// register.php
include 'inc/auth.php';
// register logic
?>
<?php
// inc/auth.php
$logged_in = false;
if (!$logged_in) {
die ('You do not have permission to access this page. Please login');
}
?>
When logging in using a form, you should check the username and password in the database. The password should be scrambled (usually done using the MD5 hash algorithm), and stored in the database in the same way. You capture the variables, using something like (use some validation to check if the POST variables are valid):
$username = $_POST['username'];
$passwordHash = md5( $_POST['password'] );
The username and hashed password should be stored in your database. You can then check for a match in the database using:
$res = mysql_query("SELECT * FROM users WHERE username='".$username."' && password='".$password."'");
When a user is found, you use sessions to store the user values, which will allow you to get access to a users information across pages. NOTE: session_start() is usually placed at the top of the page, but I'll place it here for readability.
if ( mysql_num_rows($res) ) {
session_start();
session_regenerate_id(); // regenerate session_id to help prevent session hijacking
$row = mysql_fetch_assoc($res);
$_SESSION['logged_on'] = true;
$_SESSION['username'] = $row['username'];
// add more session variables about the user as needed
}
On every page you want to protect, you add the following to the top of those pages:
session_start();
if ( !isset($_SESSION['logged_on']) ) {
header("Location: login.php"); // user is not logged in, redirect to login page
exit;
}
// page content here
There's HTTP Auth:
http://php.net/manual/en/features.http-auth.php
Or you can roll your own with a login form and session tracking:
http://www.php.net/manual/en/book.session.php.
Http auth means the user gets a pop-up dialog window asking for a username and password, it's less usual than the self-rolled version.
Enjoy!
The sites you mentioned are likely bypassable because the pages past the security check don't save and then check for login status on each page. You need to check that a visitor is logged in before access to a page is granted.
I think most users would expect form input for a login. If you want the user to come back and log in with the same account later after their session expires, you'd need a database to store user information.
When storing user information in a database, you should probably not actually store their password, either. For an example:
name password ...
-----------------------------------------------
Johnny '3858f62230ac3c915f300c664312c63f'
Alice '80338e79d2ca9b9c090ebaaa2ef293c7'
.
.
.
Johnny's password is actually "foobar", but the database stores md5('foobar'). When Johnny tries to log in, he enters his username ('Johnny') and his password ('foobar'). In PHP, you hash the password he entered, and call up his password value from the database, resulting in:
if (md5('foobar') == '3858f62230ac3c915f300c664312c63f')
This conditional is true. You can confirm if he logged in correctly, but you're never storing his actual password.
Alice's password is 'foobaz'. She tries to log in, but accidentally types 'foobar', Johnny's password. this results in:
if(md5('foobar') == '80338e79d2ca9b9c090ebaaa2ef293c7')
Which is false. Again, you don't know what Alice's password is, just that she entered the wrong one.
The downside to this strategy, of course, is that you can't tell the user what their password is when they forget it -- you don't know! You can resolve this by letting a user reset their password (to some semi-random string) instead of strait telling them what their password is.