要求用户登录
Flask-Login 提供了一个非常有用的功能——强制用户在查看应用的特定页面之前登录。 如果未登录的用户尝试查看受保护的页面,Flask-Login 将自动将用户重定向到登录表单,并且只有在登录成功后才重定向到用户想查看的页面。
为了实现这个功能,Flask-Login 需要知道哪个视图函数用于处理登录认证。在 app/ init .py 中添加代码如下:
# ...
login = LoginManager(app)
login.login_view = 'login'
上面的 'login' 值是登录视图函数(endpoint)名,换句话说该名称可用于 url_for() 函数的参数并返回对应的 URL。
Flask-Login 使用名为 @login_required 的装饰器来拒绝匿名用户的访问以保护某个视图函数。 当你将此装饰器添加到位于 @app.route 装饰器下面的视图函数上时,该函数将受到保护,不允许未经身份验证的用户访问。 以下是该装饰器如何应用于应用的主页视图函数的案例:
from flask_login import login_required
@app.route('/')
@app.route('/index')
@login_required
def index():
# ...
剩下的就是实现登录成功之后自定重定向回到用户之前想要访问的页面。 当一个没有登录的用户访问被 @login_required 装饰器保护的视图函数时,装饰器将重定向到登录页面,不过,它将在这个重定向中包含一些额外的信息以便登录后的回转。 例如,如果用户导航到 /index ,那么 @login_required 装饰器将拦截请求并以重定向到 /login 来响应,但是它会添加一个查询字符串参数来丰富这个 URL,如 /login?next=/index 。 原始 URL 设置了 next 查询字符串参数后,应用就可以在登录后使用它来重定向。
下面是一段代码,展示了如何读取和处理 next 查询字符串参数:
from flask import request
from werkzeug.urls import url_parse
@app.route('/login', methods=['GET', 'POST'])
def login():
# ...
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('index')
return redirect(next_page)
# ...
在用户通过调用 Flask-Login 的 login_user() 函数登录后,应用获取了 next 查询字符串参数的值。 Flask 提供一个 request 变量,其中包含客户端随请求发送的所有信息。 特别是 request.args 属性,可用友好的字典格式暴露查询字符串的内容。 实际上有三种可能的情况需要考虑,以确定成功登录后重定向的位置:
- 如果登录 URL 中不含
next参数,那么将会重定向到本应用的主页。 - 如果登录 URL 中包含
next参数,其值是一个相对路径(换句话说,该 URL 不含域名信息),那么将会重定向到本应用的这个相对路径。 - 如果登录 URL 中包含
next参数,其值是一个包含域名的完整 URL,那么重定向到本应用的主页。
前两种情况很好理解,第三种情况是为了使应用更安全。 攻击者可以在 next 参数中插入一个指向恶意站点的 URL,因此应用仅在重定向 URL 是相对路径时才执行重定向,这可确保重定向与应用保持在同一站点中。 为了确定 URL 是相对的还是绝对的,我使用 Werkzeug 的 url_parse() 函数解析,然后检查 netloc 属性是否被设置。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论