techwithtim / Flask-Web-App-Tutorial

Code for the note storing flask web app made during a YouTube video.
938 stars 1.03k forks source link

ValueError: Invalid hash method 'sha256' #150

Open VoxWRX opened 8 months ago

VoxWRX commented 8 months ago

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

VoxWRX commented 8 months ago

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))

mohabmohamed44 commented 7 months ago

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:

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"))
ChippieZA commented 7 months ago

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