浏览代码

Reduce remember cookie expiry, and enforce by storing it in the database

Fixes #14
session-cookie
父节点
当前提交
56c14f149f
共有 4 个文件被更改,包括 26 次插入15 次删除
  1. +1
    -0
      mysql/sql/init.sql
  2. +7
    -5
      src/app/models/session.py
  3. +12
    -8
      src/app/views/login.py
  4. +6
    -2
      src/app/views/logout.py

+ 1
- 0
mysql/sql/init.sql 查看文件

@@ -17,6 +17,7 @@ CREATE TABLE users (
CREATE TABLE cookies ( CREATE TABLE cookies (
token VARCHAR(100) UNIQUE NOT NULL, token VARCHAR(100) UNIQUE NOT NULL,
userid INT UNSIGNED NOT NULL, userid INT UNSIGNED NOT NULL,
expiry INT NOT NULL,
PRIMARY KEY (token), PRIMARY KEY (token),
FOREIGN KEY (userid) REFERENCES users(userid) FOREIGN KEY (userid) REFERENCES users(userid)
); );


+ 7
- 5
src/app/models/session.py 查看文件

@@ -2,7 +2,7 @@ from models.database import db
import mysql.connector import mysql.connector




def set_cookie(userid, token):
def set_cookie(userid, token, expiry):
""" """
Register a persistant login token for an user Register a persistant login token for an user
:param userid: The ID of the user :param userid: The ID of the user
@@ -10,10 +10,10 @@ def set_cookie(userid, token):
""" """
db.connect() db.connect()
cursor = db.cursor() cursor = db.cursor()
query = ("INSERT INTO cookies (userid, token) VALUES (%s, %s)")
query = ("INSERT INTO cookies (userid, token, expiry) VALUES (%s, %s, %s)")


try: try:
cursor.execute(query, (userid, token))
cursor.execute(query, (userid, token, expiry))
db.commit() db.commit()
except mysql.connector.Error as err: except mysql.connector.Error as err:
print("Failed executing query: {}".format(err)) print("Failed executing query: {}".format(err))
@@ -31,14 +31,16 @@ def get_cookie(token):
""" """
db.connect() db.connect()
cursor = db.cursor() cursor = db.cursor()
query = ("SELECT userid FROM cookies WHERE token = %s")
query = ("SELECT userid, expiry FROM cookies WHERE token = %s")
userid = None userid = None
expiry = None


try: try:
cursor.execute(query, (token,)) cursor.execute(query, (token,))
users = cursor.fetchall() users = cursor.fetchall()
if len(users): if len(users):
userid = users[0][0] userid = users[0][0]
expiry = users[0][1]
except mysql.connector.Error as err: except mysql.connector.Error as err:
print("Failed executing query: {}".format(err)) print("Failed executing query: {}".format(err))
cursor.fetchall() cursor.fetchall()
@@ -47,7 +49,7 @@ def get_cookie(token):
cursor.close() cursor.close()
db.close() db.close()


return userid
return userid, expiry




def delete_cookie(token): def delete_cookie(token):


+ 12
- 8
src/app/views/login.py 查看文件

@@ -6,10 +6,14 @@ from views.utils import get_nav_bar
import random import random
import string import string
import hashlib import hashlib
import time


# Get html templates # Get html templates
render = web.template.render('templates/') render = web.template.render('templates/')


# The remember cookie should be valid for a week
remember_timeout = 3600*24*7



class Login(): class Login():


@@ -58,8 +62,8 @@ class Login():
session.username = username session.username = username
session.userid = userid session.userid = userid
if remember: if remember:
rememberme = self.rememberme()
web.setcookie('remember', rememberme , 300000000)
rememberme = self.rememberme(remember_timeout)
web.setcookie('remember', rememberme , remember_timeout)


def check_rememberme(self): def check_rememberme(self):
""" """
@@ -72,17 +76,17 @@ class Login():
cookies = web.cookies() cookies = web.cookies()
# Fetch the remember cookie and convert from string to bytes # Fetch the remember cookie and convert from string to bytes
remember_token = cookies.remember remember_token = cookies.remember
userid = models.session.get_cookie(remember_token)
except AttributeError as e:
userid, expiry = models.session.get_cookie(remember_token)
except AttributeError:
# The user did not have the stored remember me cookie # The user did not have the stored remember me cookie
pass pass


# If the users signed cookie matches the host signature then log in # If the users signed cookie matches the host signature then log in
if userid is not None:
if userid is not None and expiry > time.time():
username = models.user.get_user_name_by_id(userid) username = models.user.get_user_name_by_id(userid)
self.login(username, userid, False) self.login(username, userid, False)


def rememberme(self):
def rememberme(self, timeout):
""" """
Generate a random token for the user, and store it in the database. Generate a random token for the user, and store it in the database.
""" """
@@ -91,8 +95,8 @@ class Login():


while True: while True:
token = ''.join(random.SystemRandom().choice(alphabet) for _ in range(20)) token = ''.join(random.SystemRandom().choice(alphabet) for _ in range(20))
if models.session.get_cookie(token) is None:
if models.session.get_cookie(token)[0] is None:
break break


models.session.set_cookie(session.userid, token)
models.session.set_cookie(session.userid, token, int(time.time() + timeout))
return token return token

+ 6
- 2
src/app/views/logout.py 查看文件

@@ -13,8 +13,12 @@ class Logout:
Log out of the application (kill session and reset variables) Log out of the application (kill session and reset variables)
:return: Redirect to main page :return: Redirect to main page
""" """
remember_token = web.cookies().remember
models.session.delete_cookie(remember_token)
try:
remember_token = web.cookies().remember
models.session.delete_cookie(remember_token)
except AttributeError:
# The user did not have the stored remember me cookie
pass


session = web.ctx.session session = web.ctx.session
session.username = None session.username = None


正在加载...
取消
保存