Python Flask SQL Register Login Page "hash must be unicode or bytes, not long"
Question: Im trying to create a login / register page. My register page works and I see
the information and hashed passwords added. When I try to login, I get "hash
must be unicode or bytes, not long" flashed. Please help!

    
    
        @app.route('/login/', methods=['GET','POST'])
        def login():
            try:
                c,conn = connection()
    
                if request.method == 'POST':
    
                    data = c.execute("SELECT * FROM users WHERE username = %s",
                            thwart(request.form['username']))
    
                    if sha256_crypt.verify(request.form['password'], data):
                        session['logged_in'] = True
                        session['username'] = request.form['username']
                        flash('You are now logged in.'+str(session['username']))
                        return redirect(url_for('dashboard'))
    
                else:
                    error = 'Invalid credentials. Try again'
    
                return render_template('login.html', error=error)
            except Exception, e:
                    flash(e)
    ------------------------------------------------------------------
    
         import MySQLdb
    
         def connection():
             conn = MySQLdb.connect(host="localhost",
                                    user = "root",
                                    passwd = "julie774",
                                    db = "PYTHONTUT")
             c = conn.cursor()
    
             return c, conn
    


Answer: > data = c.execute("SELECT * FROM users WHERE username = %s",
> thwart(request.form['username']))

`cursor.execute` just executes the query and returns the number of affected
rows. (see pydoc of cursor.execute). Thus in your `data` variable you have the
number of found rows.

Instead you have to fetch the data from the cursor. Also since you are
requesting all the columns from user (`*`), you will have to extract only a
particular column (the index of it — see the end note).

    
    
    c.execute("SELECT password FROM users WHERE username = %s",
                        thwart(request.form['username']))
    data = c.fetchone()
    # c.fetchone() returns None if no row has been found
    
    if sha256_crypt.verify(request.form['password'], data[0]):
        ...
    

In your example you are connecting to database without specifying the type of
the cursor, thus `c.fetchone()` will return a tuple (for example `(1L, 'John
Doe', '392347')`). And to select particular column you have to use numerical
index — `data[1]` to retrieve `'John Doe'`.

If you want named dictionary instead, you will have to specify it when
connecting to db.

    
    
    conn = MySQLdb.connect(host="localhost",
                           user = "root",
                           passwd = "***",
                           db = "PYTHONTUT",
                           cursorclass=MySQLdb.cursors.DictCursor
                           )
    

Then `c.fetchone()` will return a `dict` instead (e.g. `{'id': 1L, 'name':
'John Doe', 'password': '392347'}`) so you can use more readable
`data['name']` etc.

