我想知道如何使用会话限制对网站某些页面的访问。在夏季,我希望管理员通过与普通用户相同的登录表单登录,但是使用他输入的凭据,他将被重定向到后端页面,在该页面他可以完全访问两个前端网页和后端网页。用户登录时,只能查看前端网页。我试图避免用户登录,然后将Web浏览器的搜索栏中的URL从127.0.0.7/homepage更改为127.0.0.7/backend,并由于他已登录而被允许访问的情况。
我正在使用下面的代码检查用户是否已登录。如果未登录,则将他们重定向到登录页面。我正在使用flask框架。任何建议都将不胜感激。
谢谢。
app.route('/backend', methods=['POST', 'GET'])
def backend():
if 'userkey' in session:
# connect to database using pymysql
if cursor.rowcount == 0:
return render_template('backend.html', msg="No orders found...")
else:
rows = cursor.fetchall()
return render_template('backend.html', orderdata=rows)
elif 'userkey' not in session:
return redirect('/login')
else:
return redirect('/login')
答案 0 :(得分:0)
一旦用户通过身份验证,您必须已经在登录视图中设置了session ['userkey'],您只需要添加有关用户管理员状态的其他信息即可使此工作正常。如果将所有if 'userkey' in session
检查从视图函数之外移到装饰器中,这样可以很容易地重用它来保护所有视图函数,那么会容易得多。该模式在烧瓶文档的“需要登录的装饰器” http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/标题下显示。
在登录功能中,应在检索用户密钥和哈希密码的同时,在数据库中查询用户的管理员状态。然后,如果用户是管理员,则只需将session [“ admin”] = True设置为真;如果用户不是管理员,则根本不设置此设置。
下面的代码将对装饰器起作用。
from functools import wraps
from flask import session
def login_required(status=None):
def login_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if 'userkey' in session and (status is None or status in session):
return func(*args, **kwargs)
else:
return redirect("/login")
return wrapper
return login_decorator
然后应该应用此装饰器来保护您的所有视图功能。然后,它将在每个视图功能之前执行,如果所有条件都满足,则允许视图继续进行;如果不满足,则将用户重定向回登录页面。它具有可选的单个参数状态,在您的情况下,对于所有后端视图,该状态均应为“ admin”,而对于不需要管理员特权的前端视图,则不应提供该状态。函数内部的functools.wraps装饰器用于更新包装函数的元数据,以便使function.__name__
之类的属性按预期运行。会话检查中的“用户密钥”与您原始代码中的“用户密钥”相同,但我们还会检查是否提供了状态,如果提供了状态,则是否也将其存储在会话中。在您的情况下,状态的唯一值是“ admin”,但是可以轻松扩展此模式,以允许其他每个组都可以访问网站的不同部分。
鉴于所有用户检查均在装饰器中进行,因此后端视图功能可以简化为
@app.route('/backend', methods=['POST', 'GET'])
@login_required("admin")
def backend():
# connect to database using pymysql
if cursor.rowcount == 0:
return render_template('backend.html', msg="No orders found...")
else:
rows = cursor.fetchall()
return render_template('backend.html', orderdata=rows)
可以使用相同的装饰器来保护所有前端视图功能,只需省略“ admin”参数即可。
@app.route('/frontend', methods=['POST', 'GET'])
@login_required()
def frontend():
# .....