简体   繁体   中英

Not raising error when I log in with a wrong user, SQLITE + Tornado

I am developing a simple login application using tornado and SQLITE. When I login the application does what I expect, the user get redirected to his route, https://some_url/user_n. My problem came when I give wrong credentials, here instead to get redirected to the login area, https://some_url/login, and raise a custom error message I got a 500 generic error page. So far, I have tried everything, but I am a kind of “brand new” to python and sure to Tornado server.

Below, you can see my code:

import tornado
from tornado.web import RequestHandler
import sqlite3


# could define get_user_async instead
def get_user(request_handler):
    return request_handler.get_cookie("user")


# could also define get_login_url function (but must give up LoginHandler)
login_url = "/login"

# Initialize SQLITE3 parameters
db_file = "user_login.db"
connection = None
cursor = None

# optional login page for login_url
class LoginHandler(RequestHandler):

    def get(self):
        try:
            errormessage = self.get_argument("error")
        except Exception:
            errormessage = ""
        self.render("login.html", errormessage=errormessage)

    def check_permission(self, username, password):
        connection = sqlite3.connect(db_file)
        cursor = connection.cursor()
        cursor.execute(
            "SELECT * FROM users WHERE username=? AND password=?", (username, password)
        )
        data = cursor.fetchone()
        if username == data[1] and password == data[2]:
            return True
        return False

    def post(self):
        username = self.get_argument("username", "")
        password = self.get_argument("password", "")
        auth = self.check_permission(username, password)
        if auth:
            self.set_current_user(username)
            self.redirect(self.get_argument("next", f"/{username}"))
        else:
            error_msg = "?error=" + tornado.escape.url_escape("Login incorrect.")
            self.redirect(login_url + error_msg)

    def set_current_user(self, user):
        if user:
            self.set_cookie("user", tornado.escape.json_encode(user), expires_days=None)
        else:
            self.clear_cookie("user")


# class DashboardHandler(RequestHandler):
#     def post(self, *arg, **kwargs):
#         user_from_URL = kwargs["user_id"]
#         user_from_cookie = self.get_cookie("user", "")
#         # do_some_permission_check()
#         if user_from_URL != user_from_cookie:
#             self.redirect(self.get_argument("next", f"/{user_from_cookie}"))
 


# optional logout_url, available as curdoc().session_context.logout_url
logout_url = "/logout"


# optional logout handler for logout_url
class LogoutHandler(RequestHandler):
    def get(self, username):
        username = self.current_user
        self.clear_cookie(username)
        self.redirect(self.get_argument("next", "/login"))

The error happens in the check_permission method - you are fetching a record from the database that does not exist. This means that data = cursor.fetchone() sets the value of data to None in the case where username/password pair does not exist in the database, but you try to then get data[0] in the next line which dies with TypeError: 'NoneType' object is not subscriptable , which in turn triggers the 500 error page.

To fix the error in the question, you should fix that line to:

if data and username == data[1] and password == data[2]:

But really you should do a lot more as you shouldn't:

  • store plaintext passwords in the database (use a salted hash)
  • use set_cookie to store user data (use set_secure_cookie and only store the username)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM