上一章我们介绍了使用Flask开发基本的Web应用,并使用session来进行基本的登录授权验证,接下来我们将使用Flask-Login来进行会话管理,来处理我们的“登入、登出”问题
Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.
It will:
However, it does not:
还是上一章的Web应用,
app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.login_message = 'please login!'
login_manager.session_protection = 'strong'
logger = flask_logger.get_logger(__name__)
flask_logger.get_logger是我们自定义的日志模块,后续介绍
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
logger.debug("login post method")
username = request.form['username']
password = request.form['password']
user = flask_db.get_user_engine(username)
logger.debug('db user id is %s, detail is %s' % (user.username, user))
next_url = request.args.get("next")
logger.debug('next is %s' % next_url)
if password == 'admin123' and username == user.username:
# set login user
user = User()
user.id = username
flask_login.login_user(user)
resp = make_response(render_template('index.html', name=username))
resp.set_cookie('username', username)
if not is_safe_url(next_url):
return abort(400)
return redirect(next_url or url_for('index'))
else:
return abort(401)
logger.debug("login get method")
return render_template('login.html')
注意,用户通过验证之后,使用login_user方法让用户登录,flask_db.get_user_engine自定义获取数据库用户方法,后续介绍
当用户请求重定向到登入视图,它的请求字符串中会有一个 next 变量,其值为用户之前访问的页面,因此在我们完成验证之后,我们通过request.args.get(“next”)获取到用户之前访问的页面地址,并进行重定向,注意建议对此参数进行安全校验,避免重定向攻击
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@flask_login.login_required
def index():
logger.debug("index page, method is %s" % request.method)
return render_template('index.html', name=flask_login.current_user.id)
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}"/>
<link rel="shortcut icon" href="{{ url_for('static', filename='images/wd_favicon.ico')}}"/>
head>
<body>
<div class="htmleaf-container">
<div class="wrapper">
<div class="container">
<h1>Welcomeh1>
<form class="form" method="post" action="">
<input type="text" placeholder="Username" name="username" id="username">
<input type="password" placeholder="Password" name="password" id="password">
<button type="submit" id="login-button">Loginbutton>
form>
div>
<ul class="bg-bubbles">
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
<li>li>
ul>
div>
div>
<script src="{{ url_for('static', filename='js/jquery-2.1.1.min.js') }} " type="text/javascript">script>
<div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';color:#000000">
<h1>管理后台h1>
div>
body>
html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='js/layui/css/layui.css') }}"/>
<script src="{{ url_for('static', filename='js/jquery-2.1.1.min.js') }}" type="text/javascript">script>
<script src="{{ url_for('static', filename='js/layui/layui.js') }}" type="text/javascript">script>
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.ico')}}"/>
head>
<body>
<div style="width: 80%; float:left; margin: 10px 5px;font-family: Consolas;font-size: 20px;">
{% if name %}
Hello {{ name }}!
{% else %}
Hello World!
{% endif %}
div>
<div style="float:right; width: 10%;margin: 10px 5px;font-family: Consolas;font-size: 20px;">
<a href="#" onclick="javascript:logout();">logouta>
div>
<table class="layui-table">
<colgroup>
<col width="150">
<col width="200">
<col>
colgroup>
<thead>
<tr>
<th>昵称th>
<th>加入时间th>
<th>签名th>
tr>
thead>
<tbody>
<tr>
<td>贤心td>
<td>2016-11-29td>
<td>layuitd>
tr>
<tr>
<td>许闲心td>
<td>2016-11-28td>
<td>tabletd>
tr>
tbody>
table>
<script type="text/javascript">
var logout = function () {
window.location.href = '/logout';
}
script>
body>
html>
@app.route('/logout')
@flask_login.login_required
def logout():
# remove the username from the session if it's there
logger.debug("logout page")
flask_login.logout_user()
return redirect(url_for('login'))
至此,我们完成了使用Flask-Login的登入、登出管理,接下来,我们介绍使用Request Loader定制登录
http://www.pythondoc.com/flask-login/
http://flask-login.readthedocs.io/en/latest/#login-example
源码参考:https://github.com/ypmc/flask-sqlalchemy-web