Flask-Web-App-Tutorial icon indicating copy to clipboard operation
Flask-Web-App-Tutorial copied to clipboard

ValueError: Invalid hash method 'sha256'

Open VoxWRX opened this issue 1 year ago • 3 comments

https://github.com/techwithtim/Flask-Web-App-Tutorial/blame/ed8c8b0e589319aad6d5799e7e83103ca1faf425/website/auth.py#L59

VoxWRX avatar Mar 17 '24 21:03 VoxWRX

The error msg: File "/home/usr1/.local/lib/python3.9/site-packages/werkzeug/security.py", line 66, in _hash_internal raise ValueError(f"Invalid hash method '{method}'.") ValueError: Invalid hash method 'sha256'.

This is what i did to solve the issue: new_user = User(email=email, first_name=first_name, password=generate_password_hash(password1, method='scrypt', salt_length=16))

VoxWRX avatar Mar 17 '24 21:03 VoxWRX

Hi @VoxWRX I wish you are good

Solution for Invalid hash method 'sha256' in Flask-Login

The error "ValueError: Invalid hash method 'sha256'" indicates that the generate_password_hash function from Flask-Login doesn't support the sha256 method for password hashing.

Here's how to fix this:

1. Remove the method='sha256' argument:

The generate_password_hash function in Flask-Login uses a secure hashing algorithm by default, which is typically not sha256. Removing the method argument allows it to use the recommended method.

Here's the corrected line:

new_user = User(email=email, username=username, password=generate_password_hash(password1))


The error "ValueError: Invalid hash method 'sha256'" indicates that the `generate_password_hash` function from Flask-Login doesn't support the `sha256` method for password hashing.

Here's how to fix this:

**1. Remove the `method='sha256'` argument:**

The `generate_password_hash` function in Flask-Login uses a secure hashing algorithm by default, which is typically not `sha256`.  Removing the `method` argument allows it to use the recommended method.

Here's the corrected line:

```python
new_user = User(email=email, username=username, password=generate_password_hash(password1))

2. Update Flask-Login (if necessary):

In older versions of Flask-Login (prior to 0.5.0), sha256 might have been a supported option. If you're using a very old version, consider updating Flask-Login to benefit from the latest security improvements and potentially gain access to new features. You can update Flask-Login using pip:

pip install --upgrade Flask-Login

Important Note:

  • Never store passwords in plain text. Password hashing is a one-way process, and the original password cannot be retrieved from the hashed value. This is crucial for user security.
  • Use a strong hashing algorithm. The default algorithm used by generate_password_hash is likely more secure than sha256. Changing it unless absolutely necessary is not recommended.

By following these steps, you should be able to resolve the ValueError and ensure secure password hashing in your Flask application. and here is full code

from flask import Blueprint, render_template, redirect, url_for, request, flash
from . import db
from .models import User
from flask_login import login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash

auth = Blueprint("auth", __name__)


@auth.route("/login", methods=['GET', 'POST'])
def login():
   if request.method == 'POST':
       email = request.form.get("email")
       password = request.form.get("password")

       user = User.query.filter_by(email=email).first()
       if user:
           if check_password_hash(user.password, password):
               flash("Logged in!", category='success')
               login_user(user, remember=True)
               return redirect(url_for('views.home'))
           else:
               flash('Password is incorrect.', category='error')
       else:
           flash('Email does not exist.', category='error')

   return render_template("login.html")


@auth.route("/sign-up", methods=['GET', 'POST'])
def sign_up():
   if request.method == 'POST':
       email = request.form.get("email")
       username = request.form.get("username")
       password1 = request.form.get("password1")
       password2 = request.form.get("password2")

       email_exists = User.query.filter_by(email=email).first() if email else None
       username_exists = User.query.filter_by(username=username).first() if username else None

       if email_exists:
           flash('Email is already in use.', category='error')
       elif username_exists:
           flash('Username is already in use.', category='error')
       elif password1 != password2:
           flash('Passwords don\'t match!', category='error')
       elif username and len(username) < 2:
           flash('Username is too short.', category='error')
       elif password1 and len(password1) < 7:
           flash('Password is too short.', category='error')
       elif email is None or len(email) < 4:  # Add this condition
           flash("Email is invalid.", category='error')
       else:
           new_user = User(email=email, username=username, password=generate_password_hash(password1))
           db.session.add(new_user)
           db.session.commit()
           login_user(new_user, remember=True)
           flash('User created!')
           return redirect(url_for('views.home'))

   return render_template("signup.html")



@auth.route("/logout")
@login_required
def logout():
   logout_user()
   return redirect(url_for("views.home"))
   

mohabmohamed44 avatar Apr 03 '24 23:04 mohabmohamed44

use (password1, method='pbkdf2:sha256') ) instead of (password1, method='sha256') )

ChippieZA avatar Apr 28 '24 12:04 ChippieZA