Reputation: 15
I'm having some trouble and wondered if anyone can help me. I have an assigment from school where we're supposed to create a login/register page that saves the usernames and passwords to a text file (I know you're supposed to use a database IRL but this is for the assignment). I'm having trouble with a couple of things.
First, When I try to echo $username only the hashed passwords are shown, not the usernames. I can't figure out what I'm doing wrong.
Second, I don't know how to match the username with the correct password when I'm looping for them?
Third, I don't know if I'm using $_SESSION in the right way.
I'm very new to PHP so please go easy on me.
Here's the code, thank you!:
<?php
if (isset($_POST['submit2'])) {
$anvandare = $_POST['anvandare']; //username
$losen = $_POST['losen'];//password.
$hashlosen = password_hash($losen,PASSWORD_DEFAULT);
if (!empty($anvandare) && !empty($losen)) //If neither is empty do the following:
{
$openlogg1 = fopen('userlog.txt', 'a+'); //open userlog.txt for reading and writing.
$path1 = 'userlog.txt';
if (file_exists($path1))
{
$userdatafile = file_get_contents($path1); //Turns the file into an string.
$userdata = explode(PHP_EOL, $userdatafile);//first explode.
foreach ($userdata as $userlogin) {
$userlogin = explode(';', $userlogin); //second explode.
foreach ($userlogin as $username) {
if ($username == $anvandare){//Checking if username exists.
$usertaken = true; //if it exists $usertaken is true.
}
}
echo $username . "<br>"; //only shows hashed passwords.
}
if ($usertaken == true){ //if usertaken is true echo "username is taken".
echo "Användarnamnet är upptaget, välj ett annat.";
}
else { //otherwise write username and hashed password to userlog.txt.
fwrite($openlogg1, $anvandare .";".$hashlosen . PHP_EOL);
}
}
}
fclose($openlogg1);
}
if (isset($_POST['submit'])) {
$anvandare = $_POST['anvandare'];
$losen = $_POST['losen'];
$hashlosen = password_hash($losen,PASSWORD_DEFAULT);
if (!empty($anvandare) && !empty($losen)) { //If neither is empty do the following:
$openlogg1 = fopen('userlog.txt', 'r'); //Open userlog.txt for reading.
$path1 = 'userlog.txt';
if (file_exists($path1)) {
$userdatafile = file_get_contents($path1); //Turns file into string.
$userdata = explode(PHP_EOL, $userdatafile);//first explode
foreach ($userdata as $userlogin) {
$userlogin = explode(';', $userlogin); //second explode.
foreach ($userlogin as $username) {//Checking if username exists.
if ($username == $anvandare){ //if username equals user successuser is set to true.
$successuser = true;
}
}
echo $username . "<br>";
}
if ($successuser == true){ //If successuser is true check password.
foreach ($userdata as $password) { //Looping through password array.
if (password_verify($password, $hashlosen)) {
$successpass = true;
}
}
}
if ($successpass == true) {
$_SESSION['login'] = $anvandare;
if ($_SESSION['login'] == $anvandare){
header('Location: index.php');}
}
else {
echo "Inkorrekt användarnamn eller lösenord!";
}
}
fclose($openlogg1);
}
} ?>
Upvotes: 0
Views: 178
Reputation: 41810
First
You explode each line from the file on semicolon with
$userlogin = explode(';', $userlogin);
Then iterate the resulting array with foreach
foreach ($userlogin as $username) {
if ($username == $anvandare){//Checking if username exists.
$usertaken = true; //if it exists $usertaken is true.
}
}
At the end of that loop, $username
will be the last item in the $userlogin
array.
Since you're entering lines in the file in username;passwordhash
format, that's going to be the password.
Second
When you use password verify, you should not be comparing two hashes. The first parameter is the unhashed password as entered by the user, and the second parameter is the hash from storage.
Third
You will not be able to store values in the session unless you have started it with session_start()
.
What I would suggest, instead of iterating the lines in the file to find the user, is to read the file into an associative array, using username as key and password hash as value.
// read the rows into an array
$userFile = file('userlog.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// explode each row
$userRows = array_map(function($row) { return explode(';', $row); }, $userFile);
// reindex the array by username
$users = array_column($userRows, 1, 0);
This is less efficient than checking the file line by line, but really simplifies lookups.
All you need to do to see if a user exists is to check if their username exists as a key in the array.
if (isset($users[$_POST['anvandare']])) {
// user exists
}
And to verify the password:
$successpass = password_verify($_POST['losen'], $users[$_POST['anvandare']]);
where the first parameter is the plaintext password given by the user, and the second parameter is the hashed password taken from the file row that corresponds to the given username.
Upvotes: 0