I have seen several instances of this question but did not get a clear answer. Here is my scenario
I have a form on login.php - this should submit to loginController.php
Once loginController.php validates against the databse, it should either redirect to home.php or pass back to login.php with appropriate success / error messages
I know I can pass information back-forth between pages using SESSION but I would rather avoid using SESSION for just messages and objects that are page specific.
In JAVA we can embed objects into request object and then forward the control to the next page. Is there something equivalent in PHP?
The way I am doing it at present is as below -
1.loginController.php has the main page and it includes login.php
2.login.php resubmits the data back to loginController.php (sorta recursive submit)
3.Then there is if-then-else logic to determine whether next redirect needs to go to home.php or just include login.php once again with error messages
From our discussion, I think the following snippet may do what you want. You can use $_SESSION variable to store user data and $_POST variable to discriminate if user has submitted username and password data:
Login Controller
/* Already logged in */
if(isset($_SESSION['username'])
{
header('Location:home.html');
}
/* Not logged in */
else
{
/* Login submitted */
if(isset($_POST['submit']))
{
$user = new User(); // this is an instance of model class
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
$login_result = $user->login($username, $password);
/* Login success */
if($login_result == true)
{
$_SESSION['username'] = $username;
header('Location:home.html');
}
/* Login error */
else
{
$view_data = "Login incorrect"; // here you can set some data to be shown on login view
showView('login.html'); // pseudo code, change with your code to show login view
}
}
/* Show login form */
else
{
showView('login.html'); // pseudo code, change with your code to show login view
}
}
Login view
<?php if(!empty($view_data)) echo $view_data; /* Here you show login result (i.e. errors) */ ?>
<form method="post" action="login.html">
<input type="text" id="username" name="username" placeholder="Username" />
<input type="password" id="password" name="password" placeholder="Password" />
<input type="submit" name="submit" value="Login" />
</form>
Of course, you must implement $user->login method on user model (I strongly suggest you to use PDO statements to query database). This method simply checks user data and returns true on login success and false on failure.
On logout, simply unset($_SESSION['username']) and you're done.
I also suggest you to have a look on something like this session security question, to protect your session against hijacks. Hope it helps.
You can use query strings.
when you redirect to login.php as a result of an error, your full url will be something like:
login.php?status=error&message=invalid_credentials
in your login.php,
you can access the extra information as follows
$_GET['status'];//will contain the status
$_GET['message'];//will contain the message
Cheers!
Related
I have two pages made in PHP, index (using it as login page) and main page (this one should be protected).
Index page has a login form that asks only for password (there are no users intended to be).
I want to make this:
1. When you enter password on index page, and if it's correct, the site will redirect you to the main page. If password is not correct then it will alert you about that.
2. Main page should not be visible if you have not entered password on the index page. If you have entered it then you will be able to see the main page.
I figured out that the easiest way would be to make it with PHP session check, but it's not working on my code, so can you please help me?
So this is my PHP code for the index page. Here the site needs to check is (universal, for all) password correct, and if so it needs to redirect to main, or if not to display some alert box.
<?php
session_start();
$password = '1234';
if($_POST['password'] == $password){
//Create session
$_SESSION['session'] = 1;
// If correct redirect to main
header('Location: http://www.example.com/main');
exit;
}
else {
// If not correct stay on index (do nothing)
}
?>
Code my main page looks like this. This is where the site should check if user has session and then decide should he be able to see the site or not (if not it should redirect to index for login).
<?php
session_start();
if (!isset($_SESSION["session"]))
{
header("location: http://example.com/index");
}
?>
I Googled everything and came out with no working solution. Is there better way to achive this or can you help me fix it?
So TLDR, how to password protect main page with login (no users, same password for everyone)?
Currently this code doesn't work. When I enter password on index it redirects to main. But main page doesn't have session check working. It simply shows all without redirecting to index for login if user is without session.
Ok.. sorry for my first advice. It is obviously not a solution. But if i understand you correctly. This is my working approach:
index.php
<?php
session_start();
$password = '1234';
// Check if the user is not already logged in
if (isset($_SESSION['login'])) {
header('Location: main.php');
}
// Check if the form is submitted
if (isset($_POST['submit'])) {
if ($_POST['password'] == $password) {
$_SESSION['login'] = true;
header('Location: main.php');
}
}
?>
with form
<form action="" method="post">
<input class="upisnopolje" type="password" name="password" placeholder="Unesite kod" required>
<input class="upisnopolje" id="upisnopoljefix" type="submit" name="submit" value="Ok">
</form>
main.php
<?php
session_start();
// Check if user is logged in
if (!isset($_SESSION["login"])) {
header("location: index.php");
}
if ( isset( $_POST['submit'] ) ) {
unset($_SESSION["login"]);
header("location: index.php");
}
?>
with form to logout
<form action="" method="post">
<input type="submit" name="submit" value="Log out">
</form>
Note that submit button needs to have name="submit" for $_POST['submit'] check.
Hope it helps.
I want to make an PHP session after the visitor enters a valid password so I can display a few hidden links to the visitor, even on page reload.
<?php
if(isset($_POST['submit'])) {
$password = crypt('sumpasswurd', password_hash('rasmuslerdorf', PASSWORD_BCRYPT)); // password
if (hash_equals($password, crypt($_POST['password'], $password))) {
echo 'VALID!';
// CREATE SESSION HERE
} else {
echo 'INVALID';
}
}
if(isset($_SESSION)) echo 'YOU ARE LOGGED IN WITH A VALID PASSWORD!';
?>
<form method="POST" action="">
<input type="text" name="password">
<input type="submit" name="submit" value="OK">
</form>
How can I make this possible? And is the encryption of my form secure?
Manual session starts with session_start() function. Although you need to secure the session by some kind of user indetification logic. For instance, you have user's username and add it as a session variable and afterwards pass some kind of session id to verify that current session user is indeed loged in. Afterwards you have to check those variables in every pageload that is associated with user.
At: // CREATE SESSION HERE you might want to use something like this:
Session_start();
$_SESSION['username'] = $username;
// flollowed by session id logic
I wanted to create a dynamic signup.php. The algorithm is as follow:
Algorithm
when signup.php is requested by client, the code will attempt to check whether user send any data in $_POST.
if $_POST does not contains any data (means it's the first time user request for signup.php), a signup form will be return to the user, allowing user to enter all his/her details and again send back to signup.php through submit button.
if $_POST does contains data (means user has fill up the signup form and is now sending all the data back to signup.php), then the php code will attempt validate all those data and return result showing user has been successfully registered or error if failed to do so.
The problem I'm having right now is how am I going to check whether it's the first time user request for signup.php or not?
Use isset() to check if $_POST contains data.
http://php.net/isset
To answer your question, "how am I going to check whether it's the first time user request for signup.php or not?", honestly, probably for other users......
There are a few ways, cookies, storing request ips in a database, bleh, bleh, bleh. But...... None of them are guaranteed. The user can disable cookies, use a dynamic ip, etc. You could issue a unique hash and place it as a login.php?q=encValueForUniquePageRequest
but...... The architecture you laid out won't be practical.
Sorry :(
To check that request is POST:
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
//process new user
}
?>
Example:
<?php
Class signup_controller extends controller{
private $data = array();
private $model = array();
function __construct(Core $core){
parent::__construct($core);
/* load models - assign to model */
$this->model['page'] = $this->core->model->load('page_model', $this->core);
$this->model['auth'] = $this->core->model->load('auth_model', $this->core);
/* check script is installed - redirect */
if(empty($this->core->settings->installed)){
exit(header('Location: '.SITE_URL.'/setup'));
}
}
function index(){
/* do signup - assign error */
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if($this->model['auth']->create_user(1)===false){
$this->data['error'] = $this->model['auth']->auth->error;
}
}
/* not logged in */
if(empty($_SESSION['logged_in'])){
/* assign form keys */
$_SESSION['csrf'] = sha1(uniqid().(microtime(true)+1));
$_SESSION['userParam'] = sha1(uniqid().(microtime(true)+2));
$_SESSION['passParam'] = sha1(uniqid().(microtime(true)+3));
$_SESSION['emailParam'] = sha1(uniqid().(microtime(true)+4));
/* get partial views - assign to data */
$this->data['content_main'] = $this->core->template->loadPartial('partials/signup', null, $this->data);
$this->data['content_side'] = $this->core->template->loadPartial('about/content_side', null, $this->data);
/* layout view - assign to template */
$this->core->template->loadView('layouts/2col', 'content', $this->data);
}
/* signed in - redirect */
else{
exit(header('Location: ./user'));
}
}
}
?>
I have a number of front-end functions which are triggered based on whether or not a user is signed in (i.e. the menu items displayed), but I'm having trouble triggering them when a user signs in unless they are redirected or the page is refreshed.
How can I change the value of $logged_in to be set once a user logs in? The functions are all working properly, including setting $_SESSION['SESS_USER_ID'] = $member['user_id']; once they're signed in.
Index.php (much of this code is also used throughout the site)
At the beginning of the document:
<?php
require_once('auth.php'); // This file starts session, and checks if(!isset($_SESSION['SESS_USER_ID']) || (trim($_SESSION['SESS_USER_ID']) == ''))
require_once('config.php'); // Connects to database connection
$user_id = $_SESSION['SESS_USER_ID'];
$logged_in = (isset($_SESSION['SESS_USER_ID']));
?>
The relevant functions are then triggered by $logged_in, and follow this basic format:
<?php if ($logged_in) : ?>
// Some HTML or Script
<?php else : ?>
// Some HTML or Script
<?php endif; ?>
Sign In form & function
My apologies if some of the AJAX is irrelevant - I don't really know AJAX and re-purposed existing code.
<form id="loginForm" name="loginForm" action="login-exec_pdo.php" method="post">
<label for="user_name">Username </label><input type="text" name="user_name" required />
<label for="password">Password </label><input type="text" name="password" required />
<div id="return_result"></div><div id="messageBox5">Please complete the highlighted fields</div>
<input type="submit" id="login" value="Sign in" />
</form>
<script type="text/javascript">
$(function () { $('#loginForm').validate({
rules: {user_name: {required: true, minlength: 2,}, password: {required: true, minlength: 6,},}, messages: {user_name: "", password: "",},
errorLabelContainer: "#messageBox5",
submitHandler: function (form){
$.ajax({
type: 'POST',
url: 'login-exec_pdo.php',
data: $("#loginForm").serialize(),
success: function(data) {
if(data == "true") {
$("#loginForm").fadeOut("fast");
}
else {
writeToTarget('return_result', 'Incorrect Username or Password');
} } }); } }); });
</script>
The login-exec.php file
<?php
session_start();
require_once('config/config_pdo.php'); // Includes db connection, salt, & PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
$password = $_POST['password'];
$hashedPassword = sha1($salt . $password);
try {
$stmt_user = $conn->prepare("SELECT * FROM customer_info WHERE user_name = :user_name and password = :hashedPassword");
$stmt_user->bindValue(':user_name', $_POST['user_name'], PDO::PARAM_STR);
$stmt_user->bindValue(':hashedPassword', $hashedPassword);
$stmt_user->execute();
session_regenerate_id();
$member = $stmt_user->fetch();
if($member) {
$_SESSION['SESS_USER_ID'] = $member['user_id'];
$_SESSION['SESS_USER_NAME'] = $member['user_name'];
session_write_close();
echo "true";
exit();
}else {
echo "false";
exit();
}
}catch(PDOException $e) {
echo $e->getMessage();
}
?>
I've also tried using both javascript and php to set it in the success function within the Sign In function (where indicated above), but it either didn't set it and/or prevented the login function from completing properly. Some of the things I've tried are: if ($logged_in) : $logged_in = (isset($_SESSION['SESS_USER_ID'])); $logged_in = "true"; and $logged_in = 1;
If you're submitting the login request via AJAX, the main page's PHP won't be affected, since it's server-side and already written. If you're stuck on making the call through AJAX, you could:
1) Use the success() function to refresh the dialog/frame/whatever with the page that uses the $logged_in variable
2) Use the success() function to make another AJAX call to retrieve the page
3) Load everything (depending on how sensitive it is), but set the "logged in" material to display:none;, and use success() to do something like $('.logged-in-user-stuff').show();
Intro
It hurts my brain a bit, so let me show your obvious mistakes, first
Mistake #1
You can't set a PHP variable using JavaScript directly. This can done only by exchanging with JSON/XML
submitHandler: function (form){
$.ajax({type: 'POST', url: 'login-exec_pdo.php', data: $("#loginForm").serialize() ...
success: function(data) {
if (data == "true") {
$("#loginForm").fadeOut("fast");
// THIS IS WHERE I'VE TRIED TO SET $logged_in
// 1. You can't set $logged_in to true right from this point
// You should send JSON or XML back to PHP invoking a new nested ajax call
// and then parse that stuff in PHP and then send the parsed stuff back to JavaScript.
// However, this is some kind of bad approach, because A) you invoke a nested ajax call
// B) you make it even worse to debug and maintain C)
// 2. You serialized the form but never used it
....
Mistake #2
Mixed responsibilities and code duplication.
What exactly : Mixing database handler (including db configuration) with user responsibility (see descriptions below)
$stmt_user = $conn->prepare("SELECT * FROM customer_info WHERE user_name = :user_name and password = :hashedPassword"); <-- LIMIT 1 keyword should be appended
$stmt_user->bindValue(':user_name', $_POST['user_name'], PDO::PARAM_STR);
$stmt_user->bindValue(':hashedPassword', $hashedPassword); //<-- btw, you've missed PDO::PARAM_STR here
$stmt_user->execute();
...
session_regenerate_id(); //<-- This should be done after successful authorization, not before
$member = $stmt_user->fetch();
if($member) { //if you have error_reporting(E_ALL) you'll see a E_NOTICE
$_SESSION['SESS_USER_ID'] = $member['user_id'];
session_write_close();
echo "true"; //<-- Single quotes should be used instead of double ones.
exit();
}else {
echo "false";
exit();
}
So, ok. Assume that's a login page. But in a real-word scenarion, the profile page of the user would use a database as well.
According to your code, you would have to implement the same database handler twice or even more... (see comments below)
Mistake #3
No error tracking at all & rely on client-side validation.
Basically, you should never trust client-side validation, because anyone could just simply disable JavaScript in a browser.
And then he can easily send "invalid" data to the PHP script. Always do Server-Side validation!
But it does not mean that you should never use client-side validation at all.
Instead you should handle a situation when they come from browsers that do not have JS enabled/support.
You can try it yourself, just disable JavaScript in your browser and then enter your site...
Mistake #4
Not to mention the code duplication, the code itself isn't well structured. This is how this SHOULD NOT BE.
Here I'm saying about both JavaScript and PHP codes...
Now, how you should fix this
I'm not sure if you are going to follow above advices (in case you don't have a time or a will), so that let me answer your original question first.
How can I change the value of $logged_in to be set once a user logs
in?
In short: THIS IS A PHP VARIABLE ! And thus should be set in PHP
And it soulds like to me, even if you set $logged_in to TRUE once a user logs in, you've missed somewhere session_start().
Howewer, don't use this variable at all! Instead define a function, like, is_user_logged() because it's more reliable and "catchable" if something goes wrong.
Ok, next,
To make a life easier just define these functions:
/**
* Checks whether user logged in
*
* #return boolean TRUE if user is logged in
* FALSE if not
*/
function is_user_logged(){
//if session isn't started yet
if ( session_id() == ''){
// do start it now
session_start();
}
if ( isset($_SESSION['SESS_USER_ID']) ){
return true;
}
return false;
}
/**
* Retrieves an ID of the logged user if he's really logged
* NULL otherwise
*
* #return string|null
*/
function get_logged_user_id(){
if ( is_user_logged() === TRUE ){
return $_SESSION['SESS_USER_ID'];
}
return null;
}
/**
* "Marks" given user id as a logged one
*
* #return void
*/
function register_user_id_as_logged($id){
//will start session also if not started yet
if ( is_user_logged() !== TRUE ){
$_SESSION['SESS_USER_ID'] = $id;
}
}
Put these function at the top of the document.
Now change:
#1 in HTML template
<?php if ( TRUE === is_user_logged() ) : ?>
// Some HTML or Script if logged
<?php else : ?>
// Some HTML or Script if not logged
<?php endif; ?>
#2
...
$member = $stmt_user->fetch();
if($member) {
$_SESSION['SESS_USER_ID'] = $member['user_id'];
session_write_close();
echo "true";
exit;
to:
$member = $stmt_user->fetch();
if ($member) { //<-- Somehow my heart tells me it should be - if ( isset($member[0]) )
register_user_id_as_logged($member['user_id']); //<-- and this should be $member[0]['member_id']
session_regenerate_id();
exit('true');
if (data == "true") {
$("#loginForm").fadeOut("fast"); // <-- not required if you're going to do redirect
// THIS IS WHERE I'VE TRIED TO SET $logged_in <-- if you already in this "block", a "session id" is already set and it "works"
// all you need to do is just to redirect,like:
window.location = 'some_profile_page.php';
Now my own recomendations
Tip #1
Make sure the JavaScript isn't disabled.
You can simply do this, like,
<!DOCTYPE html>
<html>
<head>
...
<!--So, when JS is disabled, it would redirect to /error.php page automatically -->
<noscript>
<meta http-equiv="REFRESH" content="0; url=/error.php" />
</noscript>
...
</head>
...
</html>
Use this trick in all your HTML documents.
Tip #2
You should encapsulate all profile related logic into a class.
It should be similar to this one:
class Profile {
private $db;
public function __construct(PDOAdapter $db)
{
$this->db = $db;
}
public function login($username, $password)
{
//do query here and return boolean
}
public function logout()
{
//destroy session here
}
public function isLogged()
{
// check if session key exists and its a valid one here
}
private function registerAsLogged()
{
//....
}
}
I'm looking for a php script so my entire site needs a password to access. I don't want a sql database, I just want one user who's credentials are set in a variable.
I have
config.php
<?php
$secured = false;
$username = "user"; // Set manually by editing config
$password = "pass"; //Set manually by editing config
?>
Then index.html
<form action="auth.php" method="post">
Username: <input type='text' name="user" value='' />
Password: <input type='password' name="password" value='' />
<input type='submit' value='Log in' />
</form>
Then auth.php (This is what I need coded)
<?php
require once "config.php"
If $secured = false the redirect to page1.html
// So if its false don't require authentication at all anywhere on site.
If $secured = true then ask for username and password.
If wrong display error message.
If right redirect to page1.html
?>
That's what I'm trying to achieve. I then also need the login stored as a session variable so it remembers you logged in and checks on each page that you are logged in. Then finally a way to log out. So a button I can just stick somewhere will do the job. Hope this all makes sense.
Question : How does the auth.php script look like?
Thanks
You could use sessions to remember if a user has logged in. To do that, add:
session_start();
in config.php
On every page that requires log in, add this at the top of the script:
require_once('config.php');
if ($secured && (!isset($_SESSION['loggedin']) || !$_SESSION['loggedin'])) {
header('Location: index.html');
exit;
}
Auth.php should look like the following.
<?php
require_once("config.php");
If (!$secured) {
header('Location: page1.html');
exit;
}
if (isset($_POST['user']) && isset($_POST['password'])) {
if ($_POST['user']==$username && $_POST['password']==$password) {
// OK
$_SESSION['loggedin'] = true;
header('Location: page1.html');
exit;
} else {
echo "Bad login credentials. Try again";
}
} else {
// not logging in
header('Location: index.html');
exit;
}
?>
To sign out, just create a script logout.php:
<?php
require_once('config.php');
$_SESSION['loggedin'] = false;
?>
You can use session (see $_SESSION) to store if a user is logged in or not.
Once a user is logged in you can set a session that someone is logged in and then on each visit check if session exists and it is valid (using private salt and hash). If session variable does not exist or is invalid direct user to login page.