Jak zaimplementować logowanie?

0

Witam mam pewien problem ze stworzeniem działającego panelu logowania na mojej stronie a dokładniej z funkcją check_password_hash biblioteki werkzeug.security, mianowicie funkcja rejestracji działa poprawnie, dane są wysyłane do bazy danych oraz zapisywane w niej a samo hasło jest hashowane. Problem pojawia się jednak przy samym logowaniu, ponieważ mimo iż wpisuje poprawne hasło to nie zostaje rozpoczęta sesja. Poniżej zostawiam kod być może znajdzie się jakaś dobra duszyczka chcąca mi pomóc :). Dodam także że korzystam z aktualnej wersji python oraz werkzeug.
Funkcja rejestracji:

@app.route('/api/register', methods =['POST'])
def registerf():
    try:
        if request.method == 'POST':
            username = request.form['username']
            name = request.form['name']
            email = request.form['email']
            password = request.form['password']
            if username and name and email and password:
                conn = mysql.connect
                cursor = conn.cursor()
                hashed_pass = generate_password_hash(password, method='pbkdf2', salt_length=16)
                cursor.callproc('sp_createUser', (username, hashed_pass, name, email))
                data = cursor.fetchall()
                if len(data) == 0:
                    conn.commit()
                    return redirect(url_for('login'))
                else:
                    return json.dumps({'msg': 'error'})
            else:
                return json.dumps({'html': '<span>error </span>'})
    except Exception as e:
        return json.dumps({'error': str(e)})
    finally:
        cursor.close()
        conn.close()
Funkcja logowania: 
@app.route('/api/login', methods=['POST'])
def loginf():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        cursor = mysql.connection.cursor()
        cursor.callproc('sp_validateLogin', (username,))
        account = cursor.fetchone()
        if account:
            if check_password_hash(account['Haslo'], password):
                session.permanent = True
                session['loggedin'] = True
                session['id'] = account['id']
                session['username'] = account['Login']
                cursor.close()
                return redirect('/home')
            else:
                return redirect('/login')
        else:
            return redirect('/register')

PROCEDURA BAZY DANYCH sp_validateLogin

BEGIN
    select * from uzytkownik where login = username;
END
0

Sformatuj najpierw kod bo nic nie widać .
W MD kod sie formatuje za pomoca ```

0
conn = mysql.connect

czy ty w ogóle dałeś nam kod który się uruchamia? Bo to w kolejnej linijce się wywali.

2

Będzie łatwiej Ci pomóc kiedy podasz treść błędu, wartość zmiennej account, treść procedury sp_validateLogin i funkcji check_password_hash.

0

Za duży zakres testujesz, niepotrzebnie przechodzisz poprzez warstwę HTTP, może tam jest błąd, gdzieś whitespace wpada, pole się źle koduje etc.
Proponuję w jednym bloku kodu (np. dodaj nowy endpoint /test) wykonać generate_password_hash a potem od razu check_password_hash na wyniku tej poprzedniej funkcji. Wykluczysz potencjalne błędy wokoło tego kodu (który jak sam mówisz, zmodyfikowałeś, więc może w ogóle to nie ma sensu :P).

1

@Kamil Zarebski:
Użycie generate_password_hash oraz check_password_hash wygląda ok.
Sprwadź:

  1. Czy procedury sp_createUser oraz sp_validateLogin robią co należy z pozycji mysql call sp_*(...)

  2. Zobacz czy hash prawidłowo zapisuje się w bazie.
    W tym celu pobierasz selectem w mysql rekord z hashem i możesz porównać z tym co Ci wyjdzie z tym (możesz wykonać z pozycji interpretera):

    from werkzeug.security import _hash_internal
    hash,method = _hash_internal('pbkdf2','tutaj_salt_to_pomiedzy_znakami_$','haslo')
    print(hash)
    

    Być może baza danych coś tam ucina?

  3. Wyświetl co znajduje się w account z loginf tak jak pisał Ci @Krzemień. Sprawdź czy korzystasz z DictCrusor, bo odwołujesz się tak jakbyś korzystał.

  4. Sprawdź konfigurację sesji, może wydaje Ci się że problem jest w tej funkcji, a tak na prawdę jest w innym miejscu?

Uwagi:

  1. Dlaczego w loginf zamykasz cursor (linia 42) za ifem? Korzystaj z with lub try/finally.
  2. Mam nadzieję, że ta implementacja sesji to jest taka tylko przykładowa.
  3. Dlaczego z API (może że to tylko tak dla zmyłki) robisz redirecty? Albo zwracaj czysty json i obsługuj to na poziomie frontu, albo jakoś to sensownie wydziel (jak już musisz).
  4. Staraj się przekazywać pełny, możliwy do reprodukcji przykład, a nie jakiegoś "wymieszańca". Bo tak jak to podałeś, to można tylko się domyślać, nikt tego nie będzie poprawiał za Ciebie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1