Simple registration and login only reads first 2 characters of username from file, instead of 2 lines

Question:

I am trying to write a code that will work like this:

First function of the code is registration:
here the user will input their username and password, then the code will create a text file named after the username and it will include 2 lines:

1.username 
2.password 
import time 
def registracia():
    print ("To register you'll need to type your username and your password.")
    time.sleep (1.5)
    userName = input("username: ")
    time.sleep (1.5)
    passWord = input("password: ")
    filename = userName + ".txt"
    file = open(filename, "+w")
    file.write (userName+"n")
    file.write (passWord)
    file.close


if __name__ == "__main__":
    registracia()

Then there’s the 2nd function of the code and that will be login.
My thought for the login is that it will ask for input of the username, then it will open the file named after the username and read the 2nd line, after reading the line it will ask for input of password and then use if to check if the input is equal to the 2nd line.

My problem is that the readline only reads 1 letter from the username, at least that’s what I think it’s doing.

import time
print ("To login you'll need to type your username first")
def login():
        #time.sleep (1.5)
        userName = input ("username: ")
        filename = userName +".txt"
        file = open(filename, "r")
        #time.sleep (1.5)
        realPassWord = file.readline(2)
        print (realPassWord)
        passWord = input ("password: ")
        if passWord == realPassWord:
            print ("successfuly logged in ")
        elif passWord != realPassWord:
            print ("incorrect password")
            login()
login()

I’m also adding an example of input and outputs to see what’s happening:

Registration:

Input:

username: abc321
password: cba123

Output:

abc321.txt (a text file):

abc321
cba123

Login:

Input:

abc321

Output (the output shouldn’t be really visible, output is what the code will expect for the password input, but I added the print of realPassWord so I can see what the code expects):

ab

Desired output:

cba123
Asked By: totmom

||

Answers:

The logic of the code looks alright. There are just some typos or syntax errors I would like to fix.
I did not fix the style guide problems. For that I would recommend following the PEP8 Coding Guidelines, especially when naming variables. Please use snake_case for that in Python, instead of camelCase.
Also do not forget to call file.close() with the () – brackets.

import time 
def registracia():
    print("To register you'll need to type your username and your password.")
    time.sleep(1.5)
    userName = input("username: ")
    time.sleep(1.5)
    passWord = input("password: ")
    filename = userName + ".txt"
    file = open(filename, "w+")
    file.write(userName + "n" + passWord)
    file.close()


if __name__ == "__main__":
    registracia()

For the login part, the problem is, that file.readline(2) only reads the first two bytes.
Therefore you need to use something that splits your file content into lines.
In your case, you could use file.read().splitlines()[1].

import time
print ("To login you'll need to type your username first")
def login():
    #time.sleep (1.5)
    userName = input("username: ")
    filename = userName +".txt"
    file = open(filename, "r")
    #time.sleep (1.5)
    realPassWord = file.read().splitlines()[1]
    print(realPassWord)
    passWord = input("password: ")
    if passWord == realPassWord:
        print("successfuly logged in ")
    elif passWord != realPassWord:
        print("incorrect password")
        login()
login()

Just a note:

I would never recommend storing passwords as a plain text into text-files. If you consider using that seriously, then be sure to hash your passwords and maybe even store them into databases.

Answered By: lambdaxpy

The core issue with you code is how you are reading from the file.

There are a few other things I would also point out.

You are storing the username in the file but you never use it. Having the password and username in the file in plain text does not seem to be good security.

The password is also currently echoed to the terminal when it is typed in.

Python has some functionality you might want to look at:

Python has password input functionality to prompt the user for a password without echoing:

Hashing the value of the password stored in the file:

Using UUID for the file name rather than the username:

Pathlib to simplify reading and writing files:

Password compare with “constant-time compare” to reduce the risk of timing attacks

The following is not exhaustive and may not be right for your situation. It is just an example of these being used:

from getpass import getpass
from hashlib import md5, scrypt
from pathlib import Path
from secrets import token_bytes, compare_digest
import time
import uuid

SALT_SIZE = 64


def filename_uuid(filename):
    _hash = md5()
    _hash.update(filename.encode('utf-8'))
    uuid_name = uuid.UUID(_hash.hexdigest())
    return Path(f"{uuid_name}.txt")


def password_hash(password, salt):
    hash_value = scrypt(password, salt=salt, n=16384, r=8, p=1)
    return salt + hash_value


def check_password(password, stored_value):
    salt = stored_value[:SALT_SIZE]
    _password = password_hash(password, salt)
    return compare_digest(_password, stored_value)


def registracia():
    print("To register type your username and your password.")
    username = input("username: ")
    password = getpass().encode('utf8')
    salt = token_bytes(SALT_SIZE)
    token = password_hash(password, salt)
    filename = filename_uuid(username)
    filename.write_bytes(token)


def login(attempts=0):
    print("To login you'll need to type your username first")
    username = input("username: ")
    filename = filename_uuid(username)
    try:
        token = filename.read_bytes().strip()
    except FileNotFoundError:
        token = b""
    password = getpass().encode('utf8')
    if check_password(password, token):
        print("successfully logged in ")
    else:
        print("incorrect username/password combination")
        if attempts < 1:
            login(attempts + 1)


if __name__ == "__main__":
    registracia()
    login()
Answered By: ukBaz
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.