I am writing the code for a betting app (some fun personal project).
Part of my code asks every new user to create a username (their email) and a password, which it saves to a text file I created.
When a user wants to log in, it prompts them to enter their email. It loops through each line in the text file to see if the entered email is there. If it is there, it gets the line, split it, and stores the affiliated password in a variable. It then prompts the user to enter the password which it compares with the one stored in a variable. If they are the same, it acknowledges that they are logged in. If the passwords are inconsistent, the While loop continues.
If the email addresses entered in is not in the text file, it tells them Email address not linked to any account
My problem, I think, lies in the area I highlighted above. Despite providing the necessary password, it keeps telling me Email address not linked to any account
What could be wrong with my code? I have included snapshots of areas which I feel are necessary in solving this question.
def login(self):
self.line_holder = ''
self.username = input("\nEnter your email: ")
with open(r"C:\Users\"whatever.txt", 'r') as f:
for lines in f:
if self.username in lines:
self.line_holder = lines
break
if self.line_holder != '':
self.line_holder = self.line_holder.split(sep='|')
self.expected_password = self.line_holder[2]
self.enter_password = input(f"\nWelcome {self.line_holder[0]:25>}\nPlease enter your password: ")
while self.enter_password != self.expected_password:
self.enter_password = input(f"\nThis password does not match this account.\n\tEnter your password: ")
if self.enter_password == self.expected_password:
print(f"{self.line_holder[0]} you are successfully logged in.")
break
else:
print(f"\n{self.line_holder[0]} you are successfully logged in.")
break
else:
print("\nThis email address is not linked to any account.")
`
I was wondering how to store a username and password from input, and put it into a sort of database that is on the same python file. I would want the username and password to only be saved for however long the file is open, and don't require any long term storage of the data, thanks in advance!
This pretty simple stuff so I'll just give you the short answer, but you should probably do some more research on this in the future, as well provide the code you've written.
credentials = {}
def create():
username = input('Username: ')
password = input('Password: ')
credentials[username] = password
def authenticate():
username = input('Username: ')
password = input('Password: ')
return credentials[username] == password
Use create() to create users and authenticate() to log users in
In this code i am trying to use pickle to permanently store the values for the new username created when the user creates a new account but come up with logical errors. and the values in the dictionary still stay the same.(I know i am clearly missing something obvious here but I actually don't know what that is)
# defining variables
create_username = 0
create_password = 0
password = 0
username = 0
# importing pickle
import pickle
# creates a users dictionary
users = {
'Joe': 'juk725',
'Mat': 'axr3',
'Th3_j0k3r': 'bl4z3',
'ag4r-j3lly': 'Micr0b3'
}
# sign up (creating new account)
while username not in users and username != 'signup':
username = input("enter username(type signup to create an account): ")
# add new user to dictionary
if username == "signup" or username == "Signup":
create_username = input("enter a new username: ")
create_password = input("enter a new password (Your password cannot be the same as your username !!!!!!!): ")
if create_password in users:
create_password = input("password taken re-enter: ")
# then adds the new username to the users dictionary
if username == 'signup':
users[create_username] = create_password
pickle.dump(users, open('pickle_file_name.p', 'wb'))
else:
if username in users:
password = input("enter password: ")
if password in users:
print("access granted")
if username not in users:
username = input("enter username: ")
if password not in users:
print("access denied")
You're never opening the pickled file, and so your code reuses the same dictionary input repeatedly.
You should just create a script to first create the pickle file, then replace the definition of users that you have with pickle.load method call
# importing pickle
import pickle
# creates a users dictionary
with open('pickle_file_name.p', 'rb') as f:
users = pickle.load(f)
# sign up
If you want a readable file, I'd suggest json module rather than pickle. If you want to more easily query the users, then sqlite3
Also not really relevant here, but password hashing would be a good idea to learn for any such project with accounts, rather than storing data in plaintext
I've created a socket with a login system. The code below is my login class on my client system. it receives the message login successful or username/password incorrect. the print statement shows that this is getting through fine from the server so my issue isn't there or on the server part. when a password is wrong it starts back to login which is what I want it to do.the issue is when it's a correct login. the server will send login successfully and that will print but it won't break out of the loop and will just continue to ask for my username and password.
def login():
username = str(input("Please enter your username to login: "))
password = str(input("Please enter your password to login: "))
joint =(username+password)
message = hashPW(joint)
s.send(message.encode())
ls = s.recv(1024)
print(ls)
while ls != "Login successfull":
login()
else:
after_choice()
server code: I don't think this is where the problem lies. I'm pretty sure it's with the client and me being unable to break it out of the loop properly or something but I figured id add it anyway to help.
def recive():
password = c.recv(1024).decode()#reciving the password
print("Password from client: ", password)
PWcheck()
def PWcheck():
f= open("passwords.txt")
f1=f.readlines()
if password in f1:
print("Login successfull")
ls =("Login successfull")
c.send(ls.encode())
wait() #just the next class
else:
print("Username or password incorrect")
ls =("Username or password incorrect")
c.send(ls.encode())
recive()
if anyone needs more code adding i can. any help would be greatly appreciated.
I am trying to create a simple login system. What I'm doing is storing the login data in a text file called 'accounts.txt'
Now, when user tires to login, it first checks if the username given by the user is in the 'accounts.txt'. If it exists, then it asks for the password and then checks if password matches with the password in 'accounts.txt'
fr = open('accounts.txt', 'r')
while True:
username = input('Enter your username: ') # Ask for their username
if username in fr.read(): # Check if username exists
password = input('Enter password: ') # Ask for password if username exists
if username+password in fr.read():
print('Welcome ' + username)
break
else:
print('Wrong password')
Note, the password save in accounts.txt is in the format of usernamepassword so if username is jack and password is gate, the actual password in the txt file will be jackgate, hence im using username+password to check if password is correct.
The problem occuring is if the user enters correct username, then program moves ahead properly but even if the password entered is right, it still displays 'Wrong password' .When the second time user enters username, it even shows error for wrong username. I tried to play with the code for a long time but couldn't come up with a solution. I guess it has something to do with fr.read(). Can I use that 'fr' object only once?
Let me suggest some improvements with my answer to your question. I would read the accounts file in its entirety so you have an in-memory structure. If you do this as a dictionary in the form accounts[USER] -> PASS you can easily check for any account as per the code below.
Regarding my suggestions (they do not exactly only answer your questions, but IMHO the topic of writing login code should be treated with care):
I strongly recommend not to store passwords in plain text, regardless of application importance, always use hashes.
Do not store just the password hash, always use salting.
Do not tell the person trying to log in, if the username or the password was wrong, always just say "that's not the right combination", thus making it harder to break in.
Please find information about hashing functions in Python here: https://docs.python.org/3/library/hashlib.html#randomized-hashing
This site has a good introduction on salting ans securing passwords: https://crackstation.net/hashing-security.htm
Do you users a favor and treat the username as no case-sensitive. That is a totally valid approach, but it annoys me every time I have to use such a site (just like email addr are not case-sensitive)
As I am a total layman regarding password security, maybe one of the other Stackoverflow users can jump in with a comment and expand on this topic.
Anyway, here is my answer for your question on how to check for a login. I created a function check_account() that returns True or False, depending on wether the supplied credentials were correct or not.
import hashlib
import os
import binascii
def check_account(usr, pwd):
# read the accounts file, a simple CSV where
# username, salt value and password hash are
# stored in three columns separated by a pipe char
accounts = {}
fr = open('/users/armin/temp/test.csv', 'r')
for line in [x.strip().split("|") for x in fr.readlines()]:
accounts[line[0].lower()] = (line[1], line[2])
fr.close()
# now go looking if we do have the user account
# in the dictionary
if usr in accounts:
credentials = accounts[usr]
# credentials is a list with salt at index 0
# and pwd hash at index 1
# generate the hash form the functions parameters
# and compare with our account
h = hashlib.blake2b(salt=binascii.unhexlify(credentials[0]))
h.update(pwd.encode('utf-8'))
if credentials[1] == h.hexdigest():
return True
else:
return False
else:
return False
def main():
while True:
username = input('Enter your username: ') # Ask for their username
password = input('Enter password: ') # Ask for password if username exists
if check_account(username.lower(), password):
print("Welcome, {0}".format(username))
else:
print('Username or password unknown')
if __name__ == '__main__':
main()
To create the data for a user account, use may this code.
def create():
username = input('Enter your username: ').lower() # Ask for their username
password = input('Enter password: ') # Ask for password if username exists
salt = binascii.hexlify(os.urandom(hashlib.blake2b.SALT_SIZE))
print("SALT value:", salt)
h = hashlib.blake2b(salt=binascii.unhexlify(salt))
h.update(password.encode('utf-8'))
print("Pwd hash:", h.hexdigest())
You can use startswith and endswith:
fr = [i.strip('\n') for i in open('accounts.txt')]
while True:
username = input()
if any(i.startswith(username) for i in fr):
password = input('Enter password: ')
if any(username+password == i for i in fr):
print("welcome")
break
else:
print("wrong password")
I would do
if password in fr.read():
instead of
if username+password in fr.read():
This is because for it to get to the if password in fr.read loop it first has to pass the if username in fr.read loop. However, the only problem I find with this is that if they enter a correct username but enter the wrong password for that username but correct password for another username it will still pass.
That is why I think you should use a dictionary not a text file.
For example, if the usernames allowed is username and username1 and the password is username and username1, then in a different .py file, you can say.
username_password={'username':'username','username1':'username1'}
that makes a dictionary that has the username and passwords.
let's say you name that file stuff.py. Then in the second file that has to be in the same directory, you can do
from stuff import * #imports all values from stuff.py
while True:
username = input('Enter your username: ') #gets username
if username_password.has_key(username):
password = input('Enter password: ')
if password== username_password[username]:
print('Welcome '+username)
break
else:
print('Wrong password')
break
else:
print('Wrong username')
I still don't get why you have a while loop, but if you want it, it is fine. Also, I added an else loop just in case the username is wrong.