I wanted to build a super-simple login-script with a text-file. Text-file contains
password username name
Between the password, username and name is a tab. I read the file, explode it by tab, and then check the user input against the lines.
But I always get (one) Undefined offset error. I think it is because of the explode function, but I don't know why...
Here's my code:
if(!empty($_POST['login_inputEmail']) || !empty($_POST['login_inputPassword']))
{
$log = 0; //not logged in
$username = $_POST['login_inputEmail'];
$password = $_POST['login_inputPassword'];
$userdatei = fopen ("documents/user.txt","r");
while (!feof($userdatei))
{
$zeile = fgets($userdatei,800);
$userdata = explode("\t", $zeile);
if ($username == $userdata[1] && $password == trim($userdata[0]))
{
$log = 1; //logged in
}
}
fclose($userdatei);
}
Add is_array() and isset() in your code to avoid errors. Refer this
if(!empty($_POST['login_inputEmail']) || !empty($_POST['login_inputPassword']))
{
$log = 0; //not logged in
$username = $_POST['login_inputEmail'];
$password = $_POST['login_inputPassword'];
$userdatei = fopen ("documents/user.txt","r");
while (!feof($userdatei))
{
$zeile = fgets($userdatei,800);
$userdata = explode("\t", $zeile);
if(is_array($userdata))
{
if(isset($userdata[1]) && isset($userdata[0]))
{
if ($username == $userdata[1] && $password == trim($userdata[0]))
{
$log = 1; //logged in
}
}
}
}
fclose($userdatei);
}
Related
as you can see by my code, if the variable $uname and $password are not equal to the values they should be in the text file im reading from, it should print and error. Unfortunately it does not. When the values are correct however it prints both the success message and the failure message on the same line instead of just the success message. I am sure I'm overlooking something very simple but still need to ask. The code is below. Thanks in advance!
<?php
if (isset($_POST['submit'])) {
$uname = $_POST['uname'];
$pass = $_POST['pass'];
$password = sha1($pass);
$filename = "pass.txt";
$contents = file($filename, FILE_IGNORE_NEW_LINES );
foreach ($contents as $value) {
$details = explode(':', $value);
if ($uname == $details[0]&& $password == $details[1]) {
echo" Welcome, Access Has Been Granted!";
} else {
echo "Please Check User Name and Or Password";
exit;
}
}
}
?>
Your password check is inside a loop, and that loop will repeat for every line in pass.txt -- even if a line is totally empty. You should modify your code so that a $password_success variable defaults to FALSE and is only set to true if a valid, matching user/password line exists. Then, outside the loop, check $password_success exactly once.
<?php
if (isset($_POST['submit'])) {
$uname = $_POST['uname'];
$pass = $_POST['pass'];
$password = sha1($pass);
$filename = "pass.txt";
$contents = file($filename, FILE_IGNORE_NEW_LINES );
$password_success = FALSE;
foreach ($contents as $value) {
$details = explode(':', $value);
if (sizeof($details) == 2) {
if ($uname == $details[0]&& $password == $details[1]) {
$password_success = TRUE;
break; // this will stop our password file looping
}
} else {
// skip invalid password file line
}
}
if ($password_success) {
echo" Welcome, Access Has Been Granted!";
exit;
} else {
echo "Please Check User Name and Or Password";
exit;
}
}
$con = mysqli_connect('localhost', 'login', '*mypass*', 'login');
$check = "SELECT * FROM users";
$rs = mysqli_query($con, $check);
if(isset($_POST['submit'])) {
$username = strtolower($_POST['username']);
$password = hash('sha512', $_POST['password']);
if($username && $password){
while($data = mysqli_fetch_array($rs)){
if($username == $data[1]){
if($password == $data[2]){
session_start();
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
$exp = time() + (60*60*24*365);
setcookie('user', $username, $exp);
echo "test";
header("location: dash.php");
exit();
} else {
error("Incorrect Password");
}
}
}
} else {
error("Please insert your username and password");
}
}
In this code, the content of the if statement ( if($password == $data[2]) ) doesn't run correctly: only the echo function works, all the other doesn't!
Is there a solution to this issue?
I use PHP 7.0
POST:
echo "test"; was added only for testings purposes, the code doesn't work with or without it.
Looking at this part:
if($username && $password){
while($data = mysqli_fetch_array($rs)){
if($username == $data[1]){
if($password == $data[2]){
You should be careful when reading $data. Put simply, the $data array is indexed on a per-row basis starting from 0, so $data[1] and $data[2] refer to the entire second and third resultset rows, but you're not actually reading any result fields.
The right and cleaner way would be:
if($username && $password){
$data = mysqli_fetch_array($rs);
foreach ($data as $row)
{
$username = $row['field_name_with_username];
$password = $row['field_name_with_password];
... then whatever you need to do afterwards with those variables
}
If you rather stay away from the foreach looping, you can use while or for, but you need to define an interation counter (i.e. $i = 0; before entering the loop and $i++; just before the end of each iteration) and on each pass access $data[$i]['field_name_with_username'] and $data[$i]['field_name_with_password']
This is not an answer but something to try to check sessions are working.
Place the following code in its own file:
<?php
session_start();
if(isset($_SESSION['test_counter'])) {
$_SESSION['test_counter']++;
} else {
$_SESSION['test_counter'] = 1;
}
echo $_SESSION['test_counter'];
It should first display 1, and then increment the integer upon refresh.
So I'm currently learning PHP, and I'm creating a simple PHP page with a signup form using the POST method. On form submit, the page hashes the password (with phpass), verifies the username is valid (that is, it doesn't exist currently in the db) and inserts if that's true. My code is inserting new rows, but I'm not seeing values for username or hash values being stored. Here's the PHP:
require("PasswordHash.php");
$unSuccess = false;
$pwSuccess = false;
$registerSuccess = false;
$spamSuccess = false;
$database = "XXXXXXX";
$username = "XXXXXXX";
$password = "XXXXXXX";
$server = "XXXXXXX";
$db = new mysqli($server, $username, $password, $database);
$user = "";
$pass = "";
if (mysqli_connect_errno())
{
printf("Connection failed: %s\n", mysqli_connect_error());
exit();
}
if($_POST["usr"] && !$unSuccess){
$un = $_POST["usr"];
if(strlen($un) < 20){
//Verify Username is valid
if(preg_match("/([A-Za-z0-9])/", $un) == 1){
//Username is valid, check if it already exists in db.
$unCheckQuery = "SELECT USERS.Username FROM USERS WHERE USERS.Username = '$un'";
$result = $db->query($unCheckQuery);
$num = $result->num_rows;
$result->close();
if($num != 0){ $errUsername = "Username already exists."; $unSuccess = false; }
}
else{
//Username is valid and not taken
$user = $un;
$unSuccess = true;
}
}
}
if($_POST["password"] && !$pwSuccess){
//verify and hash pw
$pw = $_POST["password"];
if(str_len($pw) > 72){die("Password must be shorter than 72 characters");}
$hasher = new PasswordHash(8, false);
$hash = $hasher->HashPassword($pw);
if(strlen($hash) >= 20 && preg_match($pattern, $pw) == 1){
$pass = $hash;
echo $pass;
$pwSuccess = true;
}
else{
$pwSuccess = false;
}
}
if($_POST["spam"]){
$s = $_POST["spam"];
if($s != 10){
$spamSuccess = false;
}
else if($s == 10) {$spamSuccess = true;}
}
if($unSuccess = true && $pwSuccess = true && $spamSuccess = true){
$registerQuery = "INSERT INTO USERS(Username, phash) VALUES('$user', '$pass')";
//This line is breaking evrything.
$db->query($registerQuery);
}
The form I'm using is a simple HTML form. I have omitted login information for obvious reasons. Any pointers in the right direction would be greatly appreciated!
if($unSuccess = true && $pwSuccess = true && $spamSuccess = true)
needs to be
if($unSuccess == true && $pwSuccess == true && $spamSuccess == true)
Turns out this particular issue was being caused by a security issue on the server end. This code is syntactically correct.
if (isset($_POST['register'])) {
$email = $_POST['email'];
$username = $_POST['username'];
$pass = $_POST['password'];
$rep_pass = $_POST['rep-password'];
$firstname = $_POST['firstname'];
$surname = $_POST['surename'];
$phonenr = $_POST['phone-nr'];
$place = $_POST['place'];
}
if ($email != "" && $username != "" && $pass != "" && $rep_pass != "" && $firstname != "" && $surname != "" && $phonenr != "" && $place != "") {
}
Is there a shorter way to do the same as what I'm doing in the condition of the second if statement?
$required = ['email', 'username', 'password', ...];
foreach($required as $field)
if(empty($_POST[$field]))
throw new EpicFailureException("Mandatory field '$field' is empty");
You could use a preset accepted postvars thing.
You can add custom error messages during validation and such, and my code auto instantiates your variables. Only thing is I don't account for the dashes, but you could consider removing those from your form name's.
$accepted = array('register','email','username','password','rep-password','firstname','surename','phone-nr','place');
$_POST = array('register'=>'blah','email'=>'blah','username'=>'blah','password'=>'blah','rep-password'=>'blah','firstname'=>'blah','surename'=>'blah','phone-nr'=>'blah','place'=>'blah');
$proper = true;
$erroron = "";
foreach($accepted as $val) {
if(isset($_POST[$val])) {
trim($_POST[$val]);
if(!empty($_POST[$val])) {
$$val = $_POST[$val];
}
else {
$proper=false;
$erroron = "Error occured on $val which is empty";
break;
}
}
else {
$proper = false;
$erroron = "Error occured on $val which is not defined";
break;
}
}
if($proper) {
echo "email = $email, you might want to consider removing dashes from form names to auto instantiate those variables";
}
else {
echo "Not everything was done properly. The error message is: $erroron";
}
You can put your values into an array and then use the built in function array_filter().
If you don't provide a callback function to array_filter() it will only remove the false or empty value of your array.
Then count the value before and after the modification if they are != a value is missing.
if (isset($_POST['register'])) {
$user['email'] = $_POST['email'];
$user['username'] = $_POST['username'];
$user['pass'] = $_POST['password'];
$user['rep_pass'] = $_POST['rep-password'];
$user['firstname'] = $_POST['firstname'];
$user['surname'] = $_POST['surename'];
$user['phonenr'] = $_POST['phone-nr'];
$user['place'] = $_POST['place'];
}
$nbArg = count($user);
if($nbArg != count(array_filter($user))) {
echo "One Value is missing"
}
So, I'm trying to make a VERY BASIC login with PHP:
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$users = array("Billy", "Bob");
$passes = array("billy123", "pass1234");
for ($i = 0; $i < count($users); $i++) {
$user = $i;
if ($username === $users[$i]) {
if ($password === $passes[$user]) {
echo "Logged in as " .$users[$user];
}
}
else if ($username !== $users[$i] && $password !== $passes[$i]) {
echo "Login failed";
}
}
?>
I can't post the picture but it prints "Logged in as BillyLogin failed" exactly like that. And when I login as Bob it says "Logged in as BobLogin failed" I have no idea why though I can't seem to figure it out. Could someone explain what's going on and tell me how to fix it?
Thanks in advance.
Of course this happens, because for every username/password combination that is not a match, you echo out “Login failed” …
What you want to do instead, is loop through the whole array to see if there is a match – and only output “Login failed” after the loop if there was none.
$login_successful = false;
for ($i = 0; $i < count($users); $i++) {
if ($username === $users[$i] && $password === $passes[$i]) {
echo "Logged in as " .$users[$i];
$login_successful = true;
break; // no need to continue the loop here, so we break out of it
}
}
if (!$login_successful) {
echo "Login failed";
}
And since this will break if for some reason your $users and $passes arrays will not have the same amount of entries for any reason at some point, you should look into using a more suitable data structure as well – could f.e. be
$login_credentials = array(
arrays('username' => 'Billy', 'password' => 'billy123'),
arrays('username' => 'Bob', 'password' => 'pass1234'),
);
That is more concise, and easier to loop through as well:
$login_successful = false;
foreach ($login_credentials as $login_credential) {
if ($username === $login_credential['username'] && $password === $login_credential["password"]) {
echo 'Logged in as ' . $username;
$login_successful = true;
break; // no need to continue the loop here, so we break out of it
}
}
if (!$login_successful) {
echo 'Login failed';
}
The root if your problem is that you are not breaking out of the loop after someone has been authenticated, so it still checks against everyone else in the loop and will echo out the login status each iteration. What you want is to cache the logged in user id and if someone logs in, set the user id and break the loop. If the user id is set after the loop, they are logged in, otherwise they are not.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$users = array("Billy", "Bob");
$passes = array("billy123", "pass1234");
$user_id=-1;
for ($i = 0; $i < count($users); $i++)
{
if ($username === $users[$i] && $password === $passes[$i])
{
$user_id=$i;
break;
}
}
if($user_id>=0)
{
echo "Logged in as " .$users[$user_id];
}else
{
echo "Login failed";
}
?>
Try the code below:
$username = $_POST['user'];
$password = $_POST['pass'];
$user["Bob"]="pass";
if ($username==$user[$username]){
echo "Authenticated";
} else {
echo "bad password";
}