【发布时间】:2016-07-25 19:24:29
【问题描述】:
我已经用 flask_login 编写了 Flask 服务器。要登录用户,我使用login_user(user),并且我的站点的一页使用@login_required 保护。作为客户端,我使用 Python requests 包,代码如下:
import requests
sess = requests.session()
sess.post("http://page.on/my/site", data={"login" : "login", "password" : "password"})
通过此身份验证一切正常,但随后我尝试访问受保护的页面:
r = sess.get("http://secure.page/on/the/site")
这个请求会收到Unauthorized。
这是身份验证后设置的 cookie(现在我的服务器在 localhost 上):
<RequestsCookieJar[<Cookie session=.eJwdzjkSwjAMAMC_uE4h2dbhfCZjHR5oE1Ix_B2Gbst9l2OdeT3K_jrv3MrxjLKX5tqBGbq7MfmPiYi8aA7RAG8haZJoDZ0HrlSG6Oa1-yCqsaJNJlSVAQToNXsAt8UiFQBIbIa3bmYiarYyiEaNsUJjmlLZyn3l-c_Uzxf_2C6a.Cnf0yA.xIUSIFgcvjqwszrbwCA_D2Rqa5k for localhost.local/>]>
顺便说一句,我也用这个:
login_manager.session_protection = "strong"
如何解决这个身份验证问题?
更新:
这是服务器登录代码:
@api.route("/login/", methods=["POST"])
def handle_login_request():
login, password = str(request.form['login']).lower(), str(request.form['password'])
# Get and check user here
login_user(user)
# update user and get user_data
return jsonify(user_data)
安全路线:
@api.route("/users_of_group/")
@login_required
def get_user_of_users_group():
# code here never executes because of @login_required
api 是烧瓶蓝图的名称
UPD2:
这是sess.get返回的页面内容:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>401 Unauthorized</title>
<h1>Unauthorized</h1>
<p>The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.</p>
UPD3: 我试着用这个:
r = sess.get("http://secure.page/on/the/site", auth=("login", "password"))
在我可以看到的服务器上,首先用户成功登录,但随后服务器仍然抛出 401。
import requests
sess = requests.session()
login = sess.post("http://page.on/my/site", data={"login" : "login", "password" : "password"})
r = sess.get("http://secure.page/on/the/site", cookies=login.cookies)
同样登录用户,然后抛出 401。
UPD4:
问题似乎出在 login_user 函数中,它不会将 is_authenticated 更改为 True。我使用 SQLAlchemy,这是我的用户类:
class User(db.Model):
user_id = db.Column(db.Integer, primary_key=True)
# Many required for my app fields
is_active = db.Column(db.Boolean, default=False)
is_authenticated = db.Column(db.Boolean, default=False)
is_anonymous = db.Column(db.Boolean, default=False)
is_online = db.Column(db.Boolean, default=False)
# Init function
def get_id(self):
return str(self.user_id)
还有user_loader:
@login_manager.user_loader
def load_user(user_id):
print(user_id, type(user_id))
user = User.query.filter_by(user_id=int(user_id)).first()
print(user.login, user.is_authenticated)
return user
Id 打印正确,其类型为str,查询工作正常,但我仍然收到Unauthenticated 错误,最后print user.is_authenticated 为False。
UPD5:
实际上,在login_user 之后打印user.is_authenticated 也会显示False,即使我在login_user 之后调用了session.commit()。
【问题讨论】:
-
根据文档,[当会话保护处于活动状态时,每个请求都会为用户的计算机生成一个标识符(基本上是 IP 地址和用户代理的安全哈希) . 所以看起来这根本不是问题。你能发一个完整的minimal reproducible example吗?
-
@WayneWerner,查看我的更新答案
-
您的问题中缺少用户加载器和用户类,但我的回答很可能解决了您的问题。
标签: python authentication flask flask-sqlalchemy flask-login