Я только что написал имя пользователя и выход из системы, но я пытаюсь выяснить, каков наиболее правильный способ сделать это. Судя по документации, есть способы сделать часть кода асинхронной, нужно ли мне это делать? Я включил функции хеширования (которые я получил из stackoverflow), так что это завершено и может быть построено для очень простых приложений.
import os
import sqlite3
import hashlib
import binascii
from tornado.ioloop import IOLoop
from tornado.web import Application, RequestHandler
from tornado.options import define, options
define('port', default=80, help='port to listen on')
settings = dict(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
debug=True,
cookie_secret="changethis",
login_url="/login",
# xsrf_cookies=True,
)
def hash_password(password):
"""Hash a password for storing."""
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
pwdhash = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'),
salt, 100000)
pwdhash = binascii.hexlify(pwdhash)
return (salt + pwdhash).decode('ascii')
def verify_password(stored_password, provided_password):
"""Verify a stored password against one provided by user"""
salt = stored_password[:64]
stored_password = stored_password[64:]
pwdhash = hashlib.pbkdf2_hmac('sha512',
provided_password.encode('utf-8'),
salt.encode('ascii'), 100000)
pwdhash = binascii.hexlify(pwdhash).decode('ascii')
return pwdhash == stored_password
try:
db = sqlite3.connect('file:aaa.db?mode=rw', uri=True)
except sqlite3.OperationalError:
db = sqlite3.connect("aaa.db")
db.execute("CREATE TABLE Users (id INTEGER PRIMARY KEY, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL);")
class BaseHandler(RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("session")
class IndexHandler(BaseHandler):
def get(self):
if not self.current_user:
self.write("not logged in")
return
count = db.execute("SELECT COUNT(*) FROM Users;").fetchone()
self.write('{} users so far!'.format(count[0]))
class LoginHandler(BaseHandler):
def get(self):
if self.current_user:
self.write("already logged in")
return
self.render("login.html")
def post(self):
if self.current_user:
self.write("already logged in")
return
name=self.get_body_argument("username")
query= db.execute("SELECT COUNT(*) FROM Users WHERE username = ?;", (name,)).fetchone()
if query[0] == 0:
self.write("user does not exist")
else:
hashed_password = db.execute("SELECT (password) FROM Users WHERE username = ?;", (name,)).fetchone()[0]
if verify_password(hashed_password, self.get_body_argument("password")):
self.set_secure_cookie("session", name)
self.write("cookie set, logged in")
else:
self.write("wrong password")
class SignupHandler(BaseHandler):
def get(self):
if self.current_user:
self.write("already logged in")
return
self.render("signup.html")
def post(self):
if self.current_user:
self.write("already logged in")
return
name=self.get_body_argument("username")
password=self.get_body_argument("password")
try:
with db:
db.execute("INSERT INTO Users(username,password) VALUES (?,?);", (name, hash_password(password)))
except sqlite3.IntegrityError:
self.write("user exists")
return
self.write("user added")
class LogoutHandler(BaseHandler):
def get(self):
self.clear_cookie("session")
self.write("logged out")
def main():
routes=(
(r'/', IndexHandler),
(r'/login', LoginHandler),
(r'/logout', LogoutHandler),
(r'/signup', SignupHandler),
)
app = Application(routes, **settings)
app.listen(options.port)
IOLoop.current().start()
if __name__=="__main__":
main()