0

Hello all a problem I have run into is that I cannot login in registered users it just returns me the invalid username/password page when I try to login. Does anyone know what the problem in my code is?

  from cs50 import SQL
from flask import Flask, flash, redirect, render_template, request, session, url_for
from flask_session import Session
from passlib.apps import custom_app_context as pwd_context
from tempfile import mkdtemp

from helpers import *

# configure application
app = Flask(__name__)

# ensure responses aren't cached
if app.config["DEBUG"]:
    @app.after_request
    def after_request(response):
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Expires"] = 0
        response.headers["Pragma"] = "no-cache"
        return response

# custom filter
app.jinja_env.filters["usd"] = usd

# configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

# configure CS50 Library to use SQLite database
db = SQL("sqlite:///finance.db")

@app.route("/")
@login_required
def index():
    return apology("TODO")

@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
    """Buy shares of stock."""
    return apology("TODO")

@app.route("/history")
@login_required
def history():
    """Show history of transactions."""
    return apology("TODO")

@app.route("/login", methods=["GET", "POST"])
def login():
    """Log user in."""

    # forget any user_id
    session.clear()

    # if user reached route via POST (as by submitting a form via POST)
    if request.method == "POST":

        # ensure username was submitted
        if not request.form.get("username"):
            return apology("must provide username")

        # ensure password was submitted
        elif not request.form.get("password"):
            return apology("must provide password")

        # query database for username
        rows = db.execute("SELECT * FROM users WHERE username = :username", username=request.form.get("username"))

        # ensure username exists and password is correct
        if len(rows) != 1 or not pwd_context.verify(request.form.get("password"), rows[0]["hash"]):
            return apology("invalid username and/or password")

        # remember which user has logged in
        session["user_id"] = rows[0]["id"]

        # redirect user to home page
        return redirect(url_for("index"))

    # else if user reached route via GET (as by clicking a link or via redirect)
    else:
        return render_template("login.html")

@app.route("/logout")
def logout():
    """Log user out."""

    # forget any user_id
    session.clear()

    # redirect user to login form
    return redirect(url_for("login"))

@app.route("/quote", methods=["GET", "POST"])
@login_required
def quote():
    """Get stock quote."""
    if request.method == "POST":
        if not request.form.get("symbol"):
            return apology("missing symbol")

        #look up stock symbol and print onto quoted template
        quote = lookup(request.form.get("symbol"))
        if quote == None:
            return apology("missing correct symbol")
        return render_template("quoted.html", stock=quote.get("name"), sym=quote.get("symbol"), mon=quote.get("price"))

    return render_template("quote.html")
    #return apology("TODO")

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user."""

    if request.method == "POST":
        #make sure fields are not empty in fields
        if not request.form.get("username"):
            return apology("missing username")
        elif not request.form.get("password"):
            return apology("missing password")
        if request.form.get("password") != request.form.get("passwordc"):
            return apology("Passwords do not match")

        hash = pwd_context.encrypt("password")
        #make sure username is in database
        result = db.execute("INSERT INTO users (username, hash) VALUES(:username, :hash)", username = request.form.get("username"), hash = hash)
        if not result:
            return apology("username already exists")

        #store result incrementing id into session
        session["user_id"] = result

        return redirect(url_for("index"))

    else:
        return render_template("register.html")

@app.route("/sell", methods=["GET", "POST"])
@login_required
def sell():
    """Sell shares of stock."""
    return apology("TODO")

Im not sure if it has to do with my sessions in register def.

1
  1. I do not think, that the way how you get hash of the password is correct. Try to pass to the function a value, that the user entered, but not the string "password" hash = pwd_context.encrypt(request.form.get("password"))

  2. Look how you store user_id in session. You need to add rows = db.execute("SELECT * FROM users WHERE username = :username", username = request.form.get("username")) session["user_id"] = rows[0]["id"] because the result does not store information about "id" .The right way to access field "id" in rows is rows[0]["id"]. It means something like "give me the first row in result (if everything is correct in result will be only 1 row) and retrieve the value of the key "id" " Try to create another file tmp.py and execute following code

from cs50 import SQL db = SQL("sqlite:///finance.db") rows = db.execute("SELECT * FROM users WHERE username = :username", username = "David") print (rows)

5
  • Ah okay got it thank you for pointing out the request.form.get(password) thing. So for the session["user_id"] do I even need result can i just put the db.execute INSERT with out the result? Also rows[0]["id"] is used because the newly INSERTed id is a Primary key so it automatically goes in the first row correct? And thank you for you help! – Roundabout Jul 1 '17 at 20:44
  • @Roundabout Usernames is a unique field in the database, as well as user ID. If the username already exists in the database, then database execute will fail, so you check for that failure as follows. result = db.execute("INSERT INTO users (username, hash) VALUES(:username, :hash)", username = request.form.get("username"), hash = hash) if not result: return apology("username already exists") That' s why we need result variable. – wingedRuslan Jul 1 '17 at 20:54
  • @Roundabout, If str is a SELECT, then execute returns a list of zero or more dict objects, inside of which are keys and values representing a table’s fields and cells, respectively. The output looks like [{0} {1} {2} ... ]. Recall that username is a unique field, so when you execute SELECT WHERE username = "David" it must return only 1 row. That's why you access like rows[0]["id"] ( 1-st row , the value of "id" field) – wingedRuslan Jul 1 '17 at 21:03
  • cool understood! – Roundabout Jul 2 '17 at 0:13
  • @Roundabout , Glad I could help ;)) – wingedRuslan Jul 2 '17 at 19:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .