如何使Flask Requests模块进行身份验证?

时间:2018-03-06 16:00:12

标签: api flask python-requests

我用烧瓶构建了自己的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端点来返回我的会话令牌,但我无法访问受保护的资源,因为我似乎无法将它们保存到我的会话中。

任何人都可以帮我解决这个问题吗?

0 个答案:

没有答案