場景:
???????????web頁面如果多人用同一賬號同時登錄操作,可能會導致數據等的混亂甚至出現故障。并且可能損害開發者的利益。為此,本篇文章就講下如何實現同一賬戶同時僅能一個地方登錄操作。
思路:
??????????1. 用戶登陸時生成token(uuid.uuid4(),保存到數據庫并設定session。
2. 用戶操作視圖加一個裝飾器,這個裝飾器的功能就是驗證session[“token”]和數據庫里的token是否一至,不一致的話就返回登錄頁面,禁止操作
代碼:
----app.py
----config.py
----templates (不展示)
----static (不展示)
config.py
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
from flask import Flask,jsonify,request,redirect,render_template,session
import os
from flask_sqlalchemy import SQLAlchemy
import hashlib
import uuidbasedir = 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 innerdef 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_namesession["login_id"] = login_user.idnew_token = str(uuid.uuid4())session["token"]=new_tokenlogin_user.token = new_tokendb.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)