セッション判定回りを修正
This commit is contained in:
parent
7e580d75d0
commit
f6dc93a9ab
4
.gitignore
vendored
4
.gitignore
vendored
@ -173,4 +173,6 @@ poetry.toml
|
||||
# LSP config files
|
||||
pyrightconfig.json
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||
# End of https://www.toptal.com/developers/gitignore/api/python
|
||||
|
||||
web/data/
|
@ -5,7 +5,7 @@ services:
|
||||
- ./bot:/bot
|
||||
- ./bucket:/bot/bucket
|
||||
environment:
|
||||
- DISCORD_TOKEN=MTIyNjIwMTA4ODg1NjgyMTg4MQ.GH0q-p.5A8k4UCGXK5UT6g4uCksFNHhAky9EvRQLuZckQ
|
||||
- DISCORD_TOKEN=${DISCORD_TOKEN}
|
||||
web:
|
||||
build: ./web
|
||||
volumes:
|
||||
|
42
web/auth.py
42
web/auth.py
@ -1,12 +1,16 @@
|
||||
from flask import request, session, redirect, url_for, render_template, g, jsonify
|
||||
from flask import request, session, redirect, url_for, render_template, jsonify
|
||||
import bcrypt
|
||||
import secrets
|
||||
from db import get_db
|
||||
from models import Account, ActiveSession
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# セッションタイムアウトの設定(3分)
|
||||
SESSION_TIMEOUT = timedelta(minutes=5)
|
||||
|
||||
def login_required(f):
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not check_login(session, logger):
|
||||
@ -19,12 +23,24 @@ def check_login(session, logger):
|
||||
if 'logged_in' not in session or not session['logged_in']:
|
||||
logger.info("セッションにログイン情報がありません")
|
||||
return False
|
||||
|
||||
# セッションタイムアウトのチェック
|
||||
last_access_time = session.get('last_access_time')
|
||||
if last_access_time:
|
||||
last_access_time = datetime.strptime(last_access_time, '%Y-%m-%d %H:%M:%S.%f')
|
||||
if datetime.now() - last_access_time > SESSION_TIMEOUT:
|
||||
logger.info("セッションがタイムアウトしました")
|
||||
logout() # セッションをクリアし、ログアウト
|
||||
return False
|
||||
|
||||
db = get_db()
|
||||
active_session_count = db.query(ActiveSession).filter_by(session_id=session['session_id']).count()
|
||||
if active_session_count != 1:
|
||||
logger.info(f"セッションID {session['session_id']} のアクティブセッション数: {active_session_count}")
|
||||
return False
|
||||
|
||||
# 最後のアクセス時間を更新
|
||||
session['last_access_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
return True
|
||||
|
||||
def login():
|
||||
@ -33,12 +49,26 @@ def login():
|
||||
password = request.form['password'].encode('utf-8')
|
||||
db = get_db()
|
||||
account = db.query(Account).filter_by(user_id=user_id).first()
|
||||
|
||||
if account and bcrypt.checkpw(password, account.password.encode('utf-8')):
|
||||
active_sessions = db.query(ActiveSession).count()
|
||||
if active_sessions >= 1:
|
||||
return "他のユーザーが既にログインしています。", 403
|
||||
# 既存のアクティブセッションをチェック
|
||||
existing_session = db.query(ActiveSession).filter_by(user_id=account.id).first()
|
||||
|
||||
if existing_session:
|
||||
# セッションのタイムアウトを確認
|
||||
last_active = existing_session.last_active
|
||||
if last_active and datetime.now() - last_active > SESSION_TIMEOUT:
|
||||
# セッションがタイムアウトしている場合、削除
|
||||
db.delete(existing_session)
|
||||
db.commit()
|
||||
else:
|
||||
return "他のユーザーが既にログインしています。", 403
|
||||
|
||||
# 新しいセッションの作成
|
||||
session['logged_in'] = True
|
||||
new_session = ActiveSession(session_id=session['session_id'])
|
||||
session['session_id'] = secrets.token_hex(16)
|
||||
session['last_access_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
|
||||
new_session = ActiveSession(session_id=session['session_id'], user_id=account.id, last_active=datetime.now())
|
||||
db.add(new_session)
|
||||
db.commit()
|
||||
return redirect(url_for('index_route'))
|
||||
@ -48,7 +78,7 @@ def login():
|
||||
|
||||
def logout():
|
||||
db = get_db()
|
||||
db.query(ActiveSession).filter_by(session_id=session['session_id']).delete()
|
||||
db.query(ActiveSession).filter_by(session_id=session.get('session_id')).delete()
|
||||
db.commit()
|
||||
session.clear()
|
||||
return redirect(url_for('login_route'))
|
||||
|
@ -1,5 +1,6 @@
|
||||
from sqlalchemy import Column, Integer, String, TIMESTAMP
|
||||
from sqlalchemy import Column, Integer, String, TIMESTAMP, ForeignKey
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
@ -9,11 +10,15 @@ class Account(Base):
|
||||
user_id = Column(String)
|
||||
password = Column(String)
|
||||
|
||||
active_sessions = relationship("ActiveSession", back_populates="account")
|
||||
|
||||
class ActiveSession(Base):
|
||||
__tablename__ = 'active_sessions'
|
||||
id = Column(Integer, primary_key=True)
|
||||
session_id = Column(String)
|
||||
last_active = Column(TIMESTAMP)
|
||||
user_id = Column(Integer, ForeignKey('accounts.id'))
|
||||
account = relationship("Account", back_populates="active_sessions")
|
||||
|
||||
class ChannelId(Base):
|
||||
__tablename__ = 'channel_ids'
|
||||
|
Loading…
Reference in New Issue
Block a user