我用烧瓶构建了自己的API,但现在我正在尝试编写一个脚本来使用API,而Requests模块将不会使它超过登录。
表格 该表单有一个'用户名'输入,'密码',我也使用flask-wtf来实现csrf保护,所以有一个'csrf_token'隐藏输入。
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=1, max=20)])
password = PasswordField('Password', validators=[DataRequired(), Length(min=1, max=25)])
路线
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if request.method == 'GET':
return render_template('login.html', form=form)
elif request.method == 'POST':
if form.validate_on_submit():
credentials = {'username': request.form['username'],
'password': request.form['password']}
try:
r = requests.post('http://api.domain.com:80/authenticate', data=credentials)
response = r.json()
except Exception as e:
print('JSON Auth Error: {}'.format(e))
else:
if r.status_code is 200:
session['access_token'] = response['access_token']
session['refresh_token'] = response['refresh_token']
return redirect('/')
return render_template('login.html', form=form, error='invalid')
API端点
@api.route('/authenticate', methods=['POST'])
def authenticate():
# form data
username = request.form['username']
password = request.form['password']
# check if user exists
try:
user = User.query.filter_by(username=username).first()
except exc.SQLAlchemyError as e:
print(e)
if user and password == user.password:
tokens = generate_tokens()
return jsonify({'access_token': tokens['access'], 'refresh_token': tokens['refresh']}), 200
else:
return jsonify({'message': 'invalid login'}), 401
我尝试访问的API资源端点
@api.route('/pending', methods=['GET'])
@login_required
def pending():
@login_required验证方法
def tokens_valid():
if 'access_token' and 'refresh_token' in session:
# retrieve access and refresh tokens from session cookie
tokens = {'access_token': session['access_token'],
'refresh_token': session['refresh_token']}
# validate token endpoint
try:
r = requests.post('http://api.domain.com/validate', data=tokens)
response = r.json()
except Exception as e:
print('JSON Token Error: {}'.format(e))
else:
if r.status_code is 200:
if response['message'] == 'valid access token':
return True
elif response['message'] == 'new access token':
#set new tokens
session['access_token'] = response['access_token']
session['refresh_token'] = response['refresh_token']
return True
return False
我尝试了什么
V.1
def login():
credentials = {'username': 'username',
'password': 'password'}
s = requests.Session()
r = s.post('http://sub.domain.com/auth/login', data=credentials)
return s
V.2
def login():
login_form = requests.get('http://sub.domain.com/auth/login')
soup = BeautifulSoup(login_form.text, "html.parser")
csrf = soup.find('input', id='csrf_token').get('value')
credentials = {'username': 'username',
'password': 'password',
'csrf_token': csrf}
s = requests.Session()
r = s.post('http://sub.domain.com/auth/login', data=credentials)
return s
V.3
from flask import Flask, session
def login():
credentials = {'username': 'username',
'password': 'password'}
r = requests.post('http://api.domain.com/authenticate', data=credentials)
tokens = r.json()
session['access_token'] = tokens['access_token']
session['refresh_token'] = tokens['refresh_token']
到目前为止,我可以获得'/ authenticate'api端点来返回我的会话令牌,但我无法访问受保护的资源,因为我似乎无法将它们保存到我的会话中。
任何人都可以帮我解决这个问题吗?