我正在开发一个用Flask编写的简单Web应用程序,以便从头开始了解浏览器身份验证。作为第一步,我添加了基本身份验证,以便使用以下命令停止匿名访问:
from functools import wraps
from flask import request, Response
def check_auth(username, password):
"""This function is called to check if a username /
password combination is valid.
"""
return username == 'admin' and password == 'secret'
def authenticate():
"""Sends a 401 response that enables basic auth"""
return Response(
'Could not verify your access level for that URL.\n'
'You have to login with proper credentials', 401,
{'WWW-Authenticate': 'Basic realm="Login Required"'})
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
return authenticate()
return f(*args, **kwargs)
return decorated
来源:http://flask.pocoo.org/snippets/8/
就安全性而言,它运作良好。但问题是它提示我输入用户名和密码。一旦我提供用户名和密码,授权就会持久。所以我的问题是:
1)授权是如何持久的?基本授权是否在整个浏览器会话中存储在请求标头中?我可以看到,当我打开一个隐身窗口时,我再次需要输入一次。
2)为了使用户更友好,我是否可以拥有一个执行上述工作的登录页面,即使用纯Javscript在浏览器会话中设置持久的基本授权,并使用浏览器弹出窗口进行操作?
答案 0 :(得分:1)
你应该下载像firebug这样的工具,并根据你的要求观察标题来回。如果没有用户名和密码,您的浏览器将如何重新进行身份验证,这将具有启发性。
除非我完全误解了Flask。所有这些代码所做的就是在此行中发送一个带有基本请求质询的401
{'WWW-Authenticate': 'Basic realm="Login Required"'})
这样做是发送响应头。当浏览器获得此信息时,它会将Basic视为身份验证协议并启动对话框。此对话框是弹出的浏览器并要求输入密码,以便它可以对远程资源进行身份验证。在您执行此操作后,它将在该选项卡或浏览器的生命周期内(取决于浏览器本身)记住并发送身份验证。 Here是关于让浏览器忘记这一点的讨论(请参阅结尾很麻烦)
关于第二个问题......它基本上是this
的副本但总的来说,您需要向客户端询问凭据,然后执行协商。一些框架允许静默基本身份验证。因此,如果您获得用户名/密码,base64对其进行编码,将其推入标头中,则服务器将获得需要进行身份验证的信息。其他框架使用令牌来持久保存会话的身份验证。因此,您可以拥有不受保护的资源/login.html
,然后将表单发布到登录终点。 This似乎涵盖了基于烧瓶的登录页面。
当然这应该只通过https等来完成。