Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from flask import Blueprint, jsonify, request, session
from models.login import fetch_user
from models.login import fetch_password
import hashlib
import secrets
import hmac
login_bp = Blueprint("login",__name__)
@login_bp.route("/login", methods=["POST"])
def login():
if request.method == 'POST':
#User data from front end
data = request.get_json()
email = data.get("email")
password = data.get("password")
user = fetch_user(email) #Collect user data from database
#User authentication
if user is not None: #If database found matching email the user entered
user_email = user.get("Email") #User email from database
if user_email == email: #Checks if email returned from database is the same as what user entered
auth = fetch_password(user_email) #function returns certain columns collected from database
user_hash = auth.get("PasswordHash")
user_salt = auth.get("PasswordSalt")
user_iterations = auth.get("Iterations")
#password authentication
password_info = generate_password_hash(password)
is_correct = verify_password(password_info, password, user_salt, user_iterations, user_hash)
if is_correct == True:
session["user_id"] = user.get("UserID")
response_data = {"message":"Login Sucessful", "email": email, "session" : session["user_id"]}
return jsonify(response_data)
else:
response_data = {"message":"Email or password incorrect", "email": email}
return jsonify(response_data)
else:
return ("Email does not exist")
else:
response_data = {"message":"Email does not exist", "email": email}
return jsonify(response_data)
return {"message" : "null"}
def generate_password_hash(password):
# Generate a 16-byte salt
salt = secrets.token_bytes(16)
# Define the number of iterations
iterations = 100000
# Generate the hash using PBKDF2-HMAC-SHA-256
hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, iterations)
# Return the salt, iterations, and hash, encoded in a way that can be stored in the database
return {
'salt': salt.hex(),
'iterations': iterations,
'hash': hash.hex()
}
def verify_password(stored_password_info, submitted_password, salt, iterations, user_hash):
# Convert the stored salt back to bytes
salt = bytes.fromhex(salt)
# Use the same number of iterations as when the password was hashed
iterations = iterations
# Hash the submitted password with the stored salt and iterations
hash = hashlib.pbkdf2_hmac('sha256', submitted_password.encode(), salt, iterations)
# Compare the newly generated hash with the stored hash
# Convert the generated hash to hex for comparison
return hmac.compare_digest(hash.hex(), user_hash)