I have a table in my database for users, each user has an auth_level (1-3). On my site I have a admin page for adding/deleting new user accounts, I want to restrict access to this page only to users that have an auth level of 3.
I have been trying to get this to work with sessions but I am stuck. Hoping someone can help me out.
Here is my code for restricting access. Not sure where I have gone wrong.
the check.php start the session.
<?php
require_once('check.php');
//This function returns True if auth level = '3'
//Otherwise it returns False
function CheckAccess()
{
$result = (isset($_SESSION['SESS_AUTH_LEVEL']) && $_SESSION['SESS_AUTH_LEVEL'] == 3 );
if(!$result)
{
header('WWW-Authenticate: Basic realm=“Test restricted area”');
header('HTTP/1.0 401 Unauthorized');
return false;
}
else
{
header("location: admin.php");
}
}
?>
If I log in as a user with auth level 1 or 3, I get the same blank page.
I think you never call CheckAccess(). Calling it maybe fixes your error.
It's perfectly valid to do the following, which your function is doing.
if (this=that) { /*do multiple*/ } else //do single;
However, it appears you are not calling this function? Try this:
<?php
require_once('check.php');
CheckAccess();
?>
You are missing the closing } of your function so all the if statement is seen as part of the method by PHP.
Add a } after $result = and before if
A slightly alternative version that should achieve what you want would be
<?php
function CheckAccess() {
$result = (isset($_SESSION['SESS_AUTH_LEVEL']) && $_SESSION['SESS_AUTH_LEVEL'] == 3 );
return $result;
}
if (CheckAccess()) {
header("location: admin.php");
} else {
header('WWW-Authenticate: Basic realm=“Test restricted area”');
header('HTTP/1.0 401 Unauthorized');
}
The problem is that there is already output before the headers are send:
this need to be changed
<?php
require_once('check.php');
?>
<?php
//This function returns True if auth level = '3'
//Otherwise it returns False
function CheckAccess()
{
...
to this
<?php
require_once('check.php');
//This function returns True if auth level = '3'
//Otherwise it returns False
function CheckAccess()
{
...
because the headers needs to be sent first then the content :)
Related
Can anyone tell me why this authentication won't work?
This is a breakdown:
1) I'm trying to create a simple authentication using WWW-Authenticate with the php header() function.
2) When I go to the page, the authentication box pops up like so:
3) If I remove the script (see script below), the page loads as expected.4) No matter what password I put in or add/remove the Realm, Stale etc, nothing bites and the Authentication box just keeps looping when I click "Log In".
if( $_SERVER['PHP_AUTH_USER'] != NULL && $_SERVER['PHP_AUTH_PW'] != NULL && $_SERVER['PHP_AUTH_USER'] == ‘admin1’ && $_SERVER['PHP_AUTH_PW'] == ‘pwd1’ ) {
$_SESSION['login_flag'] = true;
} else {
header("WWW-Authenticate: Basic realm=\”Schoolroom\”, stale=FALSE");
header("HTTP/1.0 401 Unauthorized");
print "<h1>401 Unauthorized</h1>";
exit();
}
Can anyone tell me what I am doing wrong? I've also tried in multiple browsers and various computers, same issue.
UPDATE: 10:44am PST, July 5 - This is where I am at so far with modified, updated and commented code:
<?php
header('WWW-Authenticate: Basic realm="Secret page"');
header('HTTP/1.0 401 Unauthorized');
// Status flag:
$LoginSuccessful = false;
// Check username and password:
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
$Username = $_SERVER['PHP_AUTH_USER'];
$Password = $_SERVER['PHP_AUTH_PW'];
if ($Username == 'usrnm' && $Password == 'pswrd') {
$LoginSuccessful = true;
}
}
// Login passed successful?
if (!$LoginSuccessful){
/*
** The user gets here if:
**
** 1. The user entered incorrect login data (three times)
** --> User will see the error message from below
**
** 2. Or the user requested the page for the first time
** --> Then the 401 headers apply and the "login box" will
** be shown
*/
// The text inside the realm section will be visible for the
// user in the login box
//header('WWW-Authenticate: Basic realm="Secret page"');
//header('HTTP/1.0 401 Unauthorized');
print "Login failed!\n";
}
else {
// The user entered the correct login data, put
// your confidential data in here:
print 'you reached the secret page!';
}
?>
However, the script does not prompt to login window but instead renders "Login Failed".
We tested it with all available PHP versions 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 7.0, 7.1, but to no avail.
It doesn't look like you're testing to see if $_SESSION['login_flag'] is set and also true.
if(isset($_SESSION['login_flag'] && $_SESSION['login_flag'] == true)) {
//load the page without authentication
}
else {
//ask for authentication
}
I have a login page and I want to achieve this effect:
If user fails to login, display error message. After user presses refresh button, the error message should not be visible anymore.
I dont want to pass $_GET variable, for example index?page=login$failure. I want to do this in invisible in url way.
<?php
if(isset($_POST['submit_form_register'])) {
...
if($login === false) {
$user->go_to('index.php?page=login'); //Redirects back, cleaning the $_POST data.
}
..
}
?>
Now how do I say for my form, that something before redirect went bad without addint it with $_GET?
Update. So using sessions, can I do like this?
<?php
if(isset($_POST['submit_form_register'])) {
...
if($login === false) {
$_SESSION['is_form_error'] = true;
$user->go_to('index.php?page=login'); //Redirects back, cleaning the $_POST data.
}
..
}
?>
And for HTML output:
<?php if(isset($_SESSION['is_form_error']) and ($_SESSION['is_form_error'] === true)) { ?>
<div>Your email or credential is invalid.</div>
<?php } unset($_SESSION['is_form_error']); ?>
But this one doesnt work for me. I bet its because something wrong with unset. Any tips?
SOLVED: Didn't have exit; after header(); in $user->go_to($url);
You could use Session for show and hide errors
When user enter wrong user/pass you set error session and use it in view and then delete session(after showed)
`//Set Session
if (!$success) {
$_SESSION['login_error'] = 1;
}
//show
if (isset($_SESSION['login_error'])) {
echo "Invalid Username/Password";
unset($_SESSION['login_error']);
}`
Don't forget to start code with session_start();
Currently I have a very basic PHP login system. My index.php file simply checks if a session is set, if it isn't it redirects them to login.php. I see a lot of websites where the same effect is achieved but through the index of the site entirely.
For example, at http://twitter.com if I am not logged in I will land at simply twitter.com. If I am logged in I will also land at twitter.com just with different content. How can I achieve the same effect on my site?
I'm sure this is very basic but it's something I am yet to explore.
Thanks
A simple example how you can handle your welcome/user index.php site:
index.php
require_once('configFile.php'); // session_start();.. and other stuff
if ($logged) {
require_once('userLogedIn/index.php');
} else {
require_once('welcome/index.php');
}
Lots of ways to do this but the below is a primitive example. Assuming your pseudo logic is something like...
if (!$logged_in) {
redirect('login.php');
}
else {
// show page content
}
You can do...
if (!$logged_in) {
include('login.php');
}
else {
include('page-content.php');
}
The includes aren't necessarily required but help to keep it tidy.
First of all answer yourself the question if your index file can contain user supplied stuff. If so DON'T DO IT! The problem are possible attack vectors from that user supplied stuff against your login.
That said let me help you:
<?php
$session_id = session_id();
if (!empty($_COOKIE[$session_id]) && session_start() !== false && isset($_SESSION["user_id"])) {
echo "index page";
}
elseif (isset($_POST["login"])) {
// validate login ...
if ($valid_login === true) {
if (session_status() === PHP_SESSION_ACTIVE) {
session_regenerate_id();
}
else {
session_start();
}
$_SESSION["user_id"] = $user_id;
}
}
else {
echo "login page";
}
?>
I think you get the idea here. We now have a single file taking care of everything.
Im Workin on a Webapplication in PHP with CodeIgniter, and im stuck :P
Its very difficult to explain, so i show it with an example.
I have normal CodeIgniter Controller. In this Controller i have a function like this:
<?php
public function groups($subdomain ='') {
$this->load->library('MyLogin');
$user_id = $this->mylogin->logged_in();
if ($subdomain == '') {
.....
} elseif ($subdomain == 'create') {
.....
} elseif ($subdomain == 'join') {
.....
} elseif ($subdomain == 'leave') {
.....
} elseif ($subdomain == 'assign') {
.....
} else {
.....
}
}
The logged_in Function checks if the user who's loading this page (sub pages) is logged in. If not he gets automatically redirected in the logged_in function like this:
echo header("Location: /user/login");
5 Minutes ago this worked well. Now i created a new subdomain 'assign'.
Now if im not logged in and try to Connect to one of the following URLS i always get redirected
localhost/user/groups
localhost/user/groups/2
localhost/user/groups/create
localhost/user/groups/join
localhost/user/groups/leave
But if im connecting to
localhost/user/groups/assign
he tries to load this page (what does not work because the $user_id is empty).
Why the ... does this happen?
Regards Teifun2
I recommend you modify the logged_in() function from this:
echo header("Location: /user/login");
To this:
header("Location: /user/login");
exit;
I think that will solve the problem. The echo has nothing to do with it, it's just superfluous.
use $_session while logging user in...! so he will reamain logged in even after refresh and page change..! And empty values wont pass.
Halo there,
I need to change the look /design of the WWW-Authenticate popup box to match my website theme, I don't want it to show the default popup box for authentication when users need to login to secured pages. Below is the PHP script I used to create the WWW-Authenticate popup.
<?php
$_user_ = 'test';
$_password_ = 'test';
session_start();
$url_action = (empty($_REQUEST['action'])) ? 'logIn' : $_REQUEST['action'];
$auth_realm = (isset($auth_realm)) ? $auth_realm : '';
if (isset($url_action)) {
if (is_callable($url_action)) {
call_user_func($url_action);
} else {
echo 'Function does not exist, request terminated';
};
};
function logIn() {
global $auth_realm;
if (!isset($_SESSION['username'])) {
if (!isset($_SESSION['login'])) {
$_SESSION['login'] = TRUE;
header('WWW-Authenticate: Basic realm="'.$auth_realm.'"');
header('HTTP/1.0 401 Unauthorized');
echo 'You must enter a valid login and password';
echo '<p>Try again</p>';
exit;
} else {
$user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
$password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
$result = authenticate($user, $password);
if ($result == 0) {
$_SESSION['username'] = $user;
} else {
session_unset($_SESSION['login']);
errMes($result);
echo '<p>Try again</p>';
exit;
};
};
};
}
function authenticate($user, $password) {
global $_user_;
global $_password_;
if (($user == $_user_)&&($password == $_password_)) { return 0; }
else { return 1; };
}
function errMes($errno) {
switch ($errno) {
case 0:
break;
case 1:
echo 'The username or password you entered is incorrect';
break;
default:
echo 'Unknown error';
};
}
function logOut() {
session_start();
session_destroy();
header("Location: index.html");
}
?>
And the following is my code that I use in all pages I need to secure or protect.
<?php
require_once 'auth.php';
echo "You've logged in as {$_SESSION['username']}<br>";
echo '<p>LogOut</p>'
?>
Please help...And recall that the code works fine I only want to change the look. Thanx in advanced :)
Two options:
Javascript
Use javascript to construct a url in the form of http://username:password#domain.com upon form submission, set document.location to the constructed url and the browser will redirect whilst automatically authenticating.
Server Side
Allow the form to submit to itself and use server side code to perform the same redirect - I recommend using a 307 redirect.
In php:
redirect("http://username:password#domain.com", 307);
Downsides
Both versions will still result in the web browser showing the ugly authentication box if the initial username and password submission is incorrect.
If you need to avoid this scenario then you will need to implement your own server side authentication scheme.
More detail
If you can tell me which option you believe you will favour, I can show a little more example code.
Security Implications
There are security implications to using HTTP basic auth. If you do not use SSL then passwords will be sent in cleartext. Using the above methods will send the password in cleartext as part of the URL. There are other security implications too:
https://security.stackexchange.com/questions/988/is-basic-auth-secure-if-done-over-https
Because of these I would always recommend against using http basic auth. Many users may be using the same password for sensitive accounts so it's well worth investing a little time in even a basic authentication system.
You can't change the style of the pop-up box. You will have to create your own login form on your site.