#!/usr/bin/env python
# encoding: utf-8
#pip install flask-login
import datetime
from flask import Flask, Blueprint,session, redirect, url_for, render_template, request
from flask_login import LoginManager,current_user, login_user, login_required, logout_user
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
class User(UserMixin):
username = None
def __init__(self,id,username,password_hash):
self.id = id
self.username = username
self.set_password(password_hash)
def get_id(self):
return self.id
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def validate_password(self, password):
return check_password_hash(self.password_hash, password)
UserData = {
1 : User(
id=1,
username='admin',
password_hash = 'admin'
)
}
app = Flask(__name__)
app.secret_key = 's3cr3t'
login_manager = LoginManager()
# 设置不同的安全等级防止用户会话遭篡改,属性可以设为None、basic或strong
# 设为 strong 时,Flask-Login 会记录客户端 IP 地址和浏览器的用户代理信息,如果发现异动就登出用户
login_manager.session_protection = 'strong'
# 如果未登录,返回的页面
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
# Flask-Login 要求程序实现一个回调函数,使用指定的标识符加载用户
@login_manager.user_loader
def load_user(user_id):
return UserData.get(user_id)
auth = Blueprint('auth', __name__)
# 登录
@auth.get('/login')
def login():
if current_user.is_authenticated: #判断当前用户是否是登录状态
return redirect(url_for('auth.index'))
html ='''<!DOCTYPE html><html><head>
<meta charset="utf-8">
<title>登录页面</title>
</head><body>
<form action="/auth/login" method="post">
<!-- 文本输入框 -->
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required><br>
<!-- 密码输入框 -->
<label for="password">密码:</label>
<input type="password" id="password" name="password" required><br>
<!-- 提交按钮 -->
<input type="submit" value="提交">
</form>
</body>
</html>'''
return html
# 登录
@auth.post('/login')
def login_post():
try:
req = request.form
username = req.get('username')
password = req.get('password')
user = UserData.get(1)
print(username,password)
if not user:return '不存在的用户'
if username == user.username and user.validate_password(password):
duration = datetime.timedelta(seconds=30*60) # 30*60秒
remember = True
# login_user(user, remember=remember, duration=duration) # 登录
login_user(user) # 创建用户 Session
# return "ok"
return redirect(request.args.get('next') or url_for('auth.index'))
else:
return "密码不正确"
except Exception as e:
print(e)
return "error"
# 通过Flask-Login提供的login_required装饰器来增加路由保护,如果未认证用户访问这个路由,Flask-Login会将这个请求发往登录页面
@auth.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
logout_user()
return redirect(url_for('auth.login'))
# test method
@app.get('/')
@auth.get('/index')
@login_required
def index():
return "<h1>This is the first page</h1><h4><a href='/auth/login'>登录</a></h4><a href='/auth/logout'>退出登录</a>"
if __name__ == "__main__":
app.register_blueprint(auth, url_prefix='/auth')
app.run(debug=True,host='0.0.0.0',port=8080)
![]()