我正在尝试在python中编写一些REST API,首先我开始编写Authenticate代码。我在其中一个网站上找到了验证的示例代码:
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(username, password):
return authenticate()
return f(*args, **kwargs)
return decorated
我已使用上面的代码来保护我的示例应用:
@app.route('/student/<studentid>', methods = ['GET'])
@requires_auth
def api_users(studentid):
students = {'1':'ABC', '2':'XYZ', '3':'TEST'}
if studentid in students:
return jsonify({studentid:students[studentid]})
else:
return not_found()
现在,我试图通过python requests / pycurl模块调用此url。但是,无论有效的用户名/密码如何,每次返回401错误。
使用请求:
import requests, base64
usrPass = "admin:secret"
b64Val = base64.b64encode(usrPass)
from requests.auth import HTTPBasicAuth
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
res = requests.get('https://<abc.com>/student/1', auth=HTTPBasicAuth('admin','secret'), headers={'Authorization': 'Basic %s' % b64Val}, data={}, verify=False)
print res
使用curl:
myCurlPut = pycurl.Curl()
myCurlPut.setopt(pycurl.URL, "https://<abc.com>/student/1")
myCurlPut.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
myCurlPut.setopt(pycurl.USERPWD, "%s:%s" % ('admin', 'secret'))
myCurlPut.setopt(pycurl.SSL_VERIFYPEER, 0)
myCurlPut.setopt(pycurl.HTTPHEADER, ['X-HTTP-Method-Override: GET'])
myCurlPut.perform()
可以,任何人都可以帮助我每次返回401错误的原因。请建议。
答案 0 :(得分:1)
这是烧瓶授权的工作示例。
from functools import wraps
from flask import Flask,Response,request, abort
app = Flask(__name__)
def check_auth(name,passw):
return (name=='admin' and passw=='pass')
def requires_auth(f):
@wraps(f)
def decorated(*args, **kwargs):
auth = request.authorization
if not auth or not check_auth(auth.username, auth.password):
abort(401)
return f(*args, **kwargs)
return decorated
@app.route('/')
@requires_auth
def hello():
return "Hello World"
if __name__ == "__main__":
app.run(debug=True)
我的请求文件:
import requests, base64
usrPass = "admin:pass"
b64Val = base64.b64encode(usrPass)
from requests.auth import HTTPBasicAuth
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
res = requests.get('http://127.0.0.1:5000/', auth=HTTPBasicAuth('admin','pass'), headers={'Authorization': 'Basic %s' % b64Val}, data={}, verify=False)
print res
如果您在localhost上运行此命令,则应使用localhost地址
你的代码中<abc.com>
是什么。可能这就是错误。
编辑2
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired
def gen_token(name,passw, expiration=None):
s = Serializer(app.config['SECRET_KEY'], expires_in = expiration)
return s.dumps(name, passw)
def verify_token(token):
serial = Serializer(app.config['SECRET_KEY'])
try:
data = serial.loads(token)
except BadSignature:
return "Error"
except SignatureExpired:
return "Error"
name = data[0]
passw = data[1]
return name,passw
这些方法可以帮助您开始使用基于令牌的身份验证。
我做的是
答案 1 :(得分:0)
看起来您没有正确传递用户名和密码进行身份验证。您应该从username
变量获得password
和auth
的值。因此,请尝试将requires_auth
功能更改为:
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