I have a problem with my login the login works it checks the html forms and it the info is correct it will login me to the logged in page.I set the username and user id on the login page after the info is checked but the server seems like it wont save the info. Strange thing is if i logout then use the login the site works registers the username etc on the login i check the info then set the username into a variable then do
if(empty($_SESSION['username']))
{
echo "Somthing went wrong";
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=logout.php">';
}
But this does not trigger again once i go to the site for the first time in a while i need to view the logout page before i can logout even tho im not logged in of course the logout only destroys the session.
if (isset($_POST["Username"]) && !empty($_POST["Username"])) {
$salt= "";
$username23 = mysql_real_escape_string($_POST['Username']);
$thereusername = strip_tags($username23);
$password2= sha1 ($salt.$_POST["password"]);
$statement = $db->prepare("SELECT * FROM users WHERE username = ? AND password = ? ");
$statement->execute(array($thereusername,$password2));
$count = $statement->rowCount();
/// If usernam and password match we carry on
if ($count == "1"){
$username23 = mysql_real_escape_string($_POST['Username']);
$thereusername = strip_tags($username23);
$statement8 = $db->prepare("SELECT * FROM users WHERE username = ? ");
$statement8->execute(array($thereusername));
$count8 = $statement8->fetch();
$username233 = mysql_real_escape_string($count8['id']);
$_SESSION['userid'] = strip_tags($username233);
$_SESSION['username'] = $thereusername ;
if(empty($_SESSION['username'])){
echo "Somthing went wrong";
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=logout.php">';
}
if(empty($_SESSION['userid']))
{
echo "Somthing went wrong";
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=logout.php">';
}
echo "You are now being logged in";
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=dashboard.php">';
exit;
echo "works";
}
};
?>
.
<form action="login.php" method="post">
<div class="row">
<div class="form-group col-sm-6">
<label for="exampleInputEmail1">Username</label>
<input class="form-control" type="text" value="Artisanal kale" name= "Username" id="Username">
</div>
<div class="form-group col-sm-6">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" name= "password" id="password"placeholder="Password">
</div>
</div>
<div class="row">
<div class="col-sm-4">
<p> <input type="submit" value="Submit" class="btn theme-btn"> </p>
</div>
</div>
</form>
I of course use the session start at the top of the page after i login it takes me to the logged in page but will not display the username or any info ive done print_r session and get Array ( ) i then go to logout.php and login and all works perfect server error or php error ?
First off, don't do your own password salt/encrypt, you need to use password_hash() to save password hashes and password_verify() (or bcrypt equivalent) to check the hashed password vs submitted password. Second, as noted, you need to use PDO exclusively. Lastly, you need to make some classes to make your script more manageable and easier to troubleshoot. This is more complex because there are a lot of parts that need to be implemented but this is an basic example of where you should be going with your login and such. I would advise, if you don't understand the majority of this, you probably should download a framework because this type of thing is complex to do it right. Frameworks have this all built in, you just have to program the very top level of the script, for the most part...
/core/classes/App.php
class App
{
# Storage of global arrays
protected static $GlobalArray = array();
# Returns post trimmed POST array
public function getPost($key=false)
{
if(!isset(self::$GlobalArray['_POST']))
self::$GlobalArray['_POST'] = $this->sanitizeArray($_POST);
if(!empty($key))
return (isset(self::$GlobalArray['_POST'][$key]))? self::$GlobalArray['_POST'][$key] : false;
return self::$GlobalArray['_POST'];
}
# Trims the values
public function sanitizeArray($array)
{
if(!is_array($array))
return trim($array);
foreach($array as $key => $value) {
$array[$key] = $this->sanitizeArray($value);
}
return $array;
}
}
/core/classes/User.php
class User extends App
{
private $con;
public function __construct(\PDO $con)
{
$this->con = $con;
}
public function savePassword($username,$password)
{
# Create the password hash
$hash = password_hash($password);
# Prepare the query and store password hash
$query = $this->con->prepare("UPDATE users SET `password` = ? WHERE `username` = ?");
$query->execute(array($username,$password));
return $this;
}
public function validateUser($username,$password)
{
# Prepare the query to get the user
$query = $this->con->prepare("SELECT * FROM users WHERE `username` = ? LIMIT 1");
$query->execute(array($username));
# Assign password
$user = $query->fetch(\PDO::FETCH_ASSOC);
if(empty($user['password']))
return false;
# Match hash to password
if(!password_verify($password,$user['password']))
return false;
# Return the user data
return $user;
}
}
/core/classes/Session.php
class Session extends App
{
public function toSession($array)
{
foreach($array as $key => $value) {
$_SESSION[$key] = $value;
}
}
# Save to errors array
public function toError($array)
{
foreach($array as $key => $value) {
$_SESSION['errors'][$key] = $value;
}
}
# Get error
public function getError($key=false)
{
if(!empty($key))
return (isset($_SESSION['errors'][$key]))? $_SESSION['errors'][$key] : false;
return (isset($_SESSION['error']))? $_SESSION['error'] : false;
}
# Get value
public function get($key=false)
{
if(!empty($key))
return (isset($_SESSION[$key]))? $_SESSION[$key] : false;
return (isset($_SESSION))? $_SESSION : false;
}
public function start()
{
session_start();
}
public function destroy($key=false)
{
if(!empty($key)) {
if(isset($_SESSION[$key])) {
$_SESSION[$key] = null;
unset($_SESSION[$key]);
}
}
else {
session_destroy();
}
}
}
/config.php
# Create important defines
define('DS',DIRECTORY_SEPARATOR);
define('ROOT_DIR',__DIR__);
define('CORE',ROOT_DIR.DS.'core');
define('CLASSES',CORE.DS.'classes');
define('FUNCTIONS',ROOT_DIR.DS.'functions');
# A class autoloader is a must...
spl_autoload_register(function($class){
$path = str_replace(DS.DS,DS,CLASSES.DS.str_replace('\\',DS,$class).'.php');
if(is_file($path))
include_once($path);
});
# Include connection
include(FUNCTIONS.DS.'functions.php');
# Create connection
$db = mysqlconnect();
# Start the session
$Session = new Session();
$Session->start();
/login.php
# Add our config file
require_once(__DIR__.DIRECTORY_SEPARATOR.'config.php');
# Create application
$App = new User($db);
# Check if submission login
if(!empty($App->getPost("Username"))) {
# Get the user array (returns on validated)
$User = $App->validateUser($App->getPost("Username"),$App->getPost("password"));
# If user is valid
if($User){
$Session->toSession(array(
'userid'=>$User['id'],
'username'=>$User['username']
));
# Redirect & stop
header('Location: dashboard.php');
exit;
}
else {
# Store the error
$Session->toError(array("invalid_login"=>"Invalid username or password"));
# Redirect to error or whatever...
}
}
I haven't really checked this, but I have noted so you know what does what (or is supposed to do). You want to always include the config.php at the top of every top level page for consistency.
Use print_r($Session->get()); to see the session array. Also note the password check won't work if you haven't saved the password hash properly.
Related
I have a problem with my script. I have been using this same script for months. Lat week I got a message from my client that cannot access their
dashboard anymore. I check it was showing too much redirect problem. I
quickly made attempt to solve this programming but all availed. I found out
that the session actually set on the Login page because I echo it out
without redirecting, but whenever I redirect to member dashboard the session
variable will be undefined. I have gone through other people similar problem
on this forum but none were able to proffer solution to my problem. Because
this same script has been working for months. Please take a look at the code
and help me out.
This is Login page. Login.php The session actually set because when display LoginId when I echo echo it out. but lost when redirecting to another page. though It was working for more four months before this unexpected problem
<?php
require("includes/config.php");
require_once(ROOT_PATH . "main/class.member.php");
$auth_member = new MEMBER();
if($auth_member->is_loggedin() != ""){
$auth_member->redirect(BASE_URL.'member');
}
if(isset($_POST['loginMemBtn'])){
$userLoginID = strip_tags($_POST['userID']);
$password = strip_tags($_POST['password']);
if($auth_member->memberLogin($userLoginID, $password)){
$auth_member->redirect(BASE_URL.'member');
}
else{
$error[] = "Inccorrect Login Details!";
}
}
?>
class.member.php
This is the class that holds all the member details and where the session
was set. It contain MemberLogin Function
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once(ROOT_PATH.'includes/dbconnect.php');
// Class
class MEMBER{
private $connect;
public function __construct(){
$database = new Database();
$db = $database->dbConnection();
$this->connect = $db;
}
public function lastInsertId(){
return $this->connect->lastInsertId();
}
public function runQuery($sql){
$stmt = $this->connect->prepare($sql);
return $stmt;
}
public function memberLogin($userLoginID, $password){
try {
$stmt = $this->connect->prepare("SELECT * FROM members
WHERE status='Active'
AND (email=:email OR phone=:phone OR username=:email)
");
$stmt->execute(array(':email'=>$userLoginID, ':phone'=>$userLoginID));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0) {
if(password_verify($password, $userRow['password'])) {
$_SESSION['member_session'] = $userRow['login_id'];
return true;
}else{
return false;
}
}
}
catch(PDOException $e){
echo $e->getMessage();
}
}
public function is_allowuser(){
if(isset($_SESSION['member_session'])) {
return true;
}
}
public function redirect($url){
header("Location: $url");
}
public function doMememberLogout(){
session_destroy();
unset($_SESSION['member_session']);
return true;
}
}
?>
session.php this file that check whether session is set or not and it
include i to all other script
<?php
$session = new MEMBER();
if(!$session->is_allowuser()){
$session->redirect(BASE_URL.'login');
exit();
}else{
$auth_member = new MEMBER();
$loginID = $_SESSION['member_session'];
$stmt = $auth_member->runQuery("SELECT * FROM members WHERE
login_id=:loginID");
$stmt->execute(array(":loginID"=>$loginID));
$userInfo = $stmt->fetch(PDO::FETCH_ASSOC);
if($userInfo['status'] != 'Active'){
unset($_SESSION['member_session']);
}
}
?>
This is dashboard.php this is the page that member redirect to from Login
Page
<?php
require("../includes/config.php");
require_once(ROOT_PATH . "main/class.member.php");
require_once(ROOT_PATH . "main/session.php");
//echo $_SESSION['member_session'];
?>
public function redirect($url){
header("Location: $url");
exit;
}
Use exit after header call in redirect method of class.member.php file
This is a college assignment, so I know you wouldn't do this because it would be too easy to hack. I have searched so hard on this website too and I'm at a dead end. So here it is I have multiple PHP files where I am trying to pull variables across and print out hard coded user information. But my last login in function throws an error no matter what i change i keep getting different errors.This has to be done primarily with PHP and avoiding using SESSION. Any help or direction is appreciated.
My index form is straight forward.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>sample</title>
</head>
<body>
<style>
</style>
<form action="method.php"; method="POST">
Name<input type="text" name="userName">
Password<input type="text" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>
my method.php is straight forward too and works.
<?php # person
$name1= $_POST['userName'];
$password=$_POST['password'];
//echo 'testclass.php#' . $name;
include 'testclass.php';
?>
But my method credentials won't work in this, it won't find name1 or password?
<?php
class UserController {
//private $name1;
//private $password;
private $isLoggedIn = false;
// Credentials
public function credentials() {
$credentials = array(
array(
"username" => "Goat",
"password" => "1234"
),
array(
"username" => "Goat",
"password" => "1234"
)
);
return $credentials;
}
// Basic login
public function login() {
foreach ($this->credentials() as $credential) {
//not finding name 1 and password even though its been called in this php file.
if ($this->name1 == $credential['username'] && $this->password == $credential['password']) {
$this->isLoggedIn = true;
}
}
if ($isLoggedIn = true){
echo "YAYAYA";
}
else{
echo "sad";
}
}
}
$user = new UserController();
$user->credentials();
$user->login();
?>
Many thanks.
$this->name1 does not exist as a class property. You cannot access those variables like that inside your UserController. You need to pass your parameters over to the login function.
public function login($username, $password)
{
foreach ($this->credentials() as $credential)
{
if ($username == $credential['username'] && $password == $credential['password']) {
$this->isLoggedIn = true;
}
}
}
$user = new UserController();
$user->login($_POST['username'], $_POST['password']);
i am trying to get my head around sessions and how to use them to show user data and grant access to areas of the site etc...
i have session_start(); at the beginning of my config file, then proceed to do the connection to database etc...
i then have a User.php class which is as follows:
<?php
include('Password.php');
class User extends Password{
private $db;
function __construct($db){
parent::__construct();
$this->_db = $db;
}
public function is_logged_in(){
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] == true){
return true;
}
}
private function get_user_hash($username){
try {
$stmt = $this->_db->prepare('SELECT password FROM members WHERE username = :username');
$stmt->execute(array('username' => $username));
$row = $stmt->fetch();
return $row['password'];
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
}
}
public function login($username,$password){
$hashed = $this->get_user_hash($username);
if($this->password_verify($password,$hashed) == 1){
$_SESSION['loggedin'] = true;
return true;
}
}
public function logout(){
session_destroy();
}
}
?>
which when i use var_dump($_SESSION); returns:
array(1) { ["loggedin"]=> bool(true) }
what i am wanting to do is have things like "Hello, '(persons username)' welcome to the '(basic,premium,admin etc...)' area of the site".
so i think i want to be doing things like $_SESSION['memberID'], $_SESSION['username'], $_SESSION['level']
so... first of all am i looking at the right area to do this kind of thing (User.php) and would modifying anything i already have allow me to do this, or do i need to create another function(s) and query the database etc... if i do things like $_SESSION['username'] = 'mee'; then it will display 'mee', but what i am wanting to do is get the username for whichever user is logged in.
*apologies in advance if this makes little sense or is confusing, iv been trying to figure this out for some time now and literally nothing im doing makes sense - brain overload :/
For security purposes it is prudent to query the database for every subsequent request to restricted areas in your application. This can be achieved by simply storing the user id in the session variable and pulling the user data with every request by the stored user id. This way if access is revoked while the user is still logged in the system will respond correctly
This functionality could be achieved like so:
// after successfully getting user by the provided username/password
$_SESSION['logged_in_user_id'] = $user['id']
Now, on every request you simply check:
if (isset($_SESSION['logged_in_user_id'])) {
$currentUser = (new User())->find($_SESSION['logged_in_user_id']);
}
In your user model you could do something like this:
public function find($id) {
try {
$stmt = $this->_db->prepare('SELECT name, address, user_level, email FROM members WHERE id = :id');
$stmt->execute(array('id' => $id));
$row = $stmt->fetchAll();
$user = new self();
$user->fill($row[0]);
return $user;
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
} catch (Exception $e) {}
return null;
}
public function fill(array $data) {
foreach ($data as $key => $value) {
$this->$key = $value;
}
return $this;
}
To log the user out:
unset($_SESSION['logged_in_user_id']);
This method has the added benefit of keeping sensitive user data out of the plain text session files on your server which could be read by anyone with access to the box.
Now, with sessions you do need to keep in mind the potential for session hijacking but that is another discussion and there are tons of PHP packages out there to help protected against this vulnerability.
If you are not concerned with security and just want to get it working with as little effort as possible (not recommended) you can simply store the user data array in the session and use whatever you need from it:
Log in code:
public function login($username,$password){
if ($user = $this->getWithCredentials($username, $password) {
$_SESSION['logged_in_user'] = json_encode($user);
return true;
}
return false;
}
public function getWithCredentials($username, $password) {
try {
$hashedPassword = $this->myPasswordHashAlgorithm($password);
$stmt = $this->_db->prepare('SELECT id, name, address, email FROM members WHERE username = :username AND password = :password');
$stmt->execute(array('username' => $username, 'password' => $hashedPassword));
$row = $stmt->fetch();
return $row;
} catch(PDOException $e) {
echo '<p class="error">'.$e->getMessage().'</p>';
} catch (Exception $e) {}
return null;
}
Then, to get user data on subsequent requests:
$user = isset($_SESSION['logged_in_user']) ? json_decode($_SESSION['logged_in_user'] : null;
i bet there are scripts out there already about this, but I'm creating this project just for fun and to test my knowledge, now i just want the public's opinions, and if you guys find a way I could improve feel free to share as well to comment against it.
My question is simply how to create a good salt. after reading the manual, and a few book chapters this is what i came up with. Although i feel like my salt should be longer for security. what should I change?
Here is my user class. please check genSalt() function and guide me to figure out how to improve my results.
<?php
if(!defined('ACCESS_CORE')){
echo 'Permission Not Granted';
exit;
}
class user{
private $_email;
private $_pass;
private $_db;
private $_url;
function __construct(){
$this->_db = $this->db();
$this->_url = 'localhost'; //change this to ur url
if(isset($_POST['user_login'])){
$this->_email = $this->clean($_POST['user_email']); //sanitize later
$this->_pass = $this->clean($_POST['user_password']);
}
}
protected function db(){
$db = parse_ini_file('../contra.conf');
$this->_db = new mysqli($db['host'], $db['user'], $db['pass'], $db['name']);
if ($this->_db->connect_errno) {
trigger_error("Failed to connect to MySQL".$mysqli->connect_errno). $mysqli->connect_error;
}
}
protected function clean($string){
return mysql_real_escape_string($string); #TODO: add more options html etc
}
public function safeReferer(){
$ref = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); //if there is a ref..
if(empty($ref) || strpos($ref, $this->_url)){
return true;
} else {
return false;
}
}
public function includeForm($message = ""){ #TODO: finish form view page
?>
<div id="logForm">
<h3>User Authentication Form</h3>
<?php echo ($message === "") ? '' : $message; ?>
<form id="loginForm" method="post" action="login.php">
<input type="text" name="user_email" />
<input type="password" name="user_password" />
<input type="submit" value="Login" name="user_login" />
<a href="/" >Forgot password?</a>
</form>
</div>
<?php ;
}
protected function genSalt($length) { #TODO: improve something is fishy
$prefix = '$2a$'.$length.'$'; //blowfish prefix
//base64 unique random alphanumeric
$uniqRand = base64_encode(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
$modified_string = str_replace('+', '.', $uniqRand);
$salt = substr($modified_string, 0, $length);
return $prefix.$salt.'$';
}
protected function correctPass($password, $salt){ #TODO: change to prepared statement. best method?
$sql = "SELECT pass, s FROM users WHERE email = '$this->_email'";
if($result = $this->_db->query($sql)){
while ($row = $result->fetch_object()) {
if(cript($row['pass'], $row['s']) === $row['s']){
return true;
} else {
return false;
}
}
}
}
public function login(){
if($this->correctPass($this->_email, $this->_pass)){
echo 'create session, session cookie, start timeout, and redirect'; #TODO: copy login, finish page on form view
} else {
$message = '<h5>Please try again</h5>';
$message .= '<p>It looks like you have either entered a wrong user name or password.';
$this->includeForm($message);
}
}
// test function, similar function in register class
public function createPass($pass){
$salt = $this->genSalt(10);
$hash = crypt($pass, $salt);
echo $salt. '--';
echo 'hashed pass : '. $hash;
echo '<br> entered pass : '.$pass.'<br>';
if(crypt($pass, $hash) == $hash ){
echo 'true';
} else {
echo 'false';
}
}
}
?>
test function results...
$2a$10$WlUvRqsgZl$--
hashed pass : $2a$10$WlUvRqsgZl$$$$$$$$$$$. tRNdwECDQXhN07g4mIp82xxFCTUev3m
entered pass : mypassword
true
Why not consider the password_hash function? It also hashes but generates a random salt every time and uses blowfish by default. It requires PHP 5.5 or later, however.
i build a website and it has a sign in form, when user sign in, the sign in form will not appear, and a sign out will apprear instead
my problem is when the user sign out the session doesn't destroy
when user sign in , i got to the function run, when user sign out i go to the function sign out
HTML
<?php
Session::init();
$l = Session::get('loggedIn');
if (isset($l) && $l==true) {
?>
sign out
<?php
} else {
?>
Sign in
<br/>
<form action="<?php echo URL;?>login/run" method="POST">
<div class="staticSignin">
phoneNumber
password
</div>
<div id="userInputSignin">
<input type="text" name="MNumber"/>
<input type="password" name="password"/>
<input type="image" src="http://localhost/Mar7ba/public/images/signinButton.png"/>
</div>
</form>
<?php
}
?>
run for sign in
Session::init();
$row = $sth->fetch();
$ID = $row['ID'];
$rollID = $row['rollID'];
Session::set('loggedIn', true);
Session::set('ID', $ID);
Session::set('roolOfUser', $rollID);
sign out
public function signout() {
Session::set("loggedIn", false);
Session::destroy();
$this->view->render('index/index');
}
Session Class
<?php
class Session {
public static function init() {
session_start();
}
public static function set($key, $value) {
#$_SESSION[$key] = $value;
}
public static function get($key) {
if (isset($_SESSION[$key]))
return $_SESSION[$key];
}
public static function destroy() {
unset ($_SESSION);
session_destroy();
}
}
when sign out , the sign in form doesn't appear
To destroy a session you need first to start it using session_start(), seems that you aren't doing this
Try to do it:
session_start();
// Deleting all content in $_SESSION
$_SESSION = array();
// Destroying the session
session_destroy();
EDIT 1
Try to do these changes in destroy() to test if the session is really being started:
public static function destroy() {
session_start();
// Deleting all content in $_SESSION
$_SESSION = array();
// Destroying the session
session_destroy();
}