Flask一个用户同时只能在一处登录实现

场景:

web页面如果多人用同一账号同时登录操作,可能会导致数据等的混乱甚至出现故障。并且可能损害开发者的利益。为此,本篇文章就讲下如何实现同一账户同时仅能一个地方登录操作。

思路:

  1. 用户登陆时生成token(uuid.uuid4(),保存到数据库并设定session。

  2. 用户操作视图加一个装饰器,这个装饰器的功能就是验证session["token"]和数据库里的token是否一至,不一致的话就返回登录页面,禁止操作

代码:

----app.py

----config.py

----templates (不展示)

----static (不展示)

config.py

python 复制代码
import os
from datetime import timedelta
basedir = os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:passworld@localhost:3306/singlelogin?charset=utf8'
SQLALCHEMY_TRACK_MODIFICATIONS = False
PERMANENT_SESSION_LIFETIME=timedelta(hours=6)

app.py

python 复制代码
from flask import Flask,jsonify,request,redirect,render_template,session
import os
from flask_sqlalchemy import SQLAlchemy
import hashlib
import uuid

basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.secret_key = "your secret key"
app.config.from_object("config")
db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    passwd = db.Column(db.String(128))
    token = db.Column(db.String(128),default=None)
    def __repr__(self):
        return self.name
with app.app_context():
    db.create_all()



def loginVaild(fun):
    def inner(*args, **kwargs):
        userid=session.get("login_id")
        session_token=session.get("token")
        userinfo=User.query.filter_by(id=userid).first()
        if userinfo.token==session_token:
            return fun(*args, **kwargs)
        else:
            return render_template("login.html")
    return inner

def setPassword(password):
    password += "the string you like"
    md5 = hashlib.md5()
    md5.update(password.encode())
    result = md5.hexdigest()
    return result


@app.route("/index",methods=["GET"])
@app.route("/",methods=["GET"])
@loginVaild
def index():
    print(session)
    return jsonify(msg="dddd")

@app.route("/login",methods=["GET","POST"])
def login():
    if request.method == "POST":
        user_name = request.form.get("user_name")
        user_pwd = request.form.get("user_pwd")
        if not user_pwd or not user_name:
            data = "用户名和密码不能为空!"
            return render_template("login.html", data=data, usr=user_name)
        login_user = User.query.filter_by(name=user_name).first()
        if not login_user:
            data = "用户名不存在!"
            return render_template("login.html", data=data, usr=user_name)
        s_pwd = setPassword(user_pwd)
        if s_pwd != login_user.passwd:
            data = "密码错误!"
            return render_template("login.html", data=data, usr=user_name)
        session["login_name"] = user_name
        session["login_id"] = login_user.id
        new_token = str(uuid.uuid4())
        session["token"]=new_token
        login_user.token = new_token
        db.session.commit()
        return redirect("/index")
    return render_template("login.html")

@app.route("/register",methods=["GET","POST"])
def refister():
    if request.method == "GET":
        return render_template("register.html")
    else:
        user_name = request.form.get("user_name")
        if User.query.filter_by(name=user_name).first():
            return jsonify(msg="用户名已存在!")
        user_pwd = request.form.get("user_pwd")
        user_pwd = setPassword(user_pwd)
        user = User(name=user_name, passwd=user_pwd)
        db.session.add(user)
        db.session.commit()
        return jsonify(msg="SUCCESS")

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=8080)

如有错误,欢迎斧正

相关推荐
田里的水稻5 分钟前
C++_python_相互之间的包含调用方法
c++·chrome·python
2501_9418705610 分钟前
面向微服务熔断与流量削峰策略的互联网系统稳定性设计与多语言工程实践分享
开发语言·python
GIS之路1 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
勇哥java实战分享1 小时前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要1 小时前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
IT=>小脑虎1 小时前
Python零基础衔接进阶知识点【详解版】
开发语言·人工智能·python
智航GIS1 小时前
10.6 Scrapy:Python 网页爬取框架
python·scrapy·信息可视化
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪1 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
清水白石0081 小时前
解构异步编程的两种哲学:从 asyncio 到 Trio,理解 Nursery 的魔力
运维·服务器·数据库·python