Parcourir la source

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

Fixes #14
session-cookie
Sindre Stephansen il y a 5 ans
Parent
révision
56c14f149f
4 fichiers modifiés avec 26 ajouts et 15 suppressions
  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 Voir le fichier

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


+ 7
- 5
src/app/models/session.py Voir le fichier

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


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

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

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

return userid
return userid, expiry


def delete_cookie(token):


+ 12
- 8
src/app/views/login.py Voir le fichier

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

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

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


class Login():

@@ -58,8 +62,8 @@ class Login():
session.username = username
session.userid = userid
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):
"""
@@ -72,17 +76,17 @@ class Login():
cookies = web.cookies()
# Fetch the remember cookie and convert from string to bytes
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
pass

# 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)
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.
"""
@@ -91,8 +95,8 @@ class Login():

while True:
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

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

+ 6
- 2
src/app/views/logout.py Voir le fichier

@@ -13,8 +13,12 @@ class Logout:
Log out of the application (kill session and reset variables)
: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.username = None


Chargement…
Annuler
Enregistrer