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:
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.