未经授权的访问和令牌不起作用

时间:2018-10-03 09:13:08

标签: python security authentication curl

在尝试进行Flask身份验证工作时,我一直在苦苦挣扎。 我正在使用以下示例:https://github.com/miguelgrinberg/REST-auth/blob/master/api.py

我在mysql数据库中有一个用户,我可以生成一个令牌,但是每当我使用它发出cURL请求时,都会获得带有 Exception Bad Signature 异常的未经授权的访问。 这是我的代码:

Users.py:

# coding=utf-8

from sqlalchemy import Column, String, Date, Integer, Numeric, Enum
from common.base import Base
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import relationship, deferred
from model.DictSerializable import DictSerializable
from passlib.apps import custom_app_context as pwd_context
from itsdangerous import (TimedJSONWebSignatureSerializer
                          as Serializer, BadSignature, SignatureExpired)

class Users( Base, DictSerializable ):
    __tablename__ = 'users'
    id = Column(Integer, primary_key = True)
    username = Column(String(32), index = True)
    password_hash = Column(String(128))

    def __init__( self, username, password ):
        self.username = username  
        self.password = password

    def hash_password(self, password):
        self.password_hash = pwd_context.encrypt(password)

    def verify_password(self, password):
        return pwd_context.verify(password, self.password_hash)

    def generate_auth_token(self, expiration=3600):
        s = Serializer('SECRET KEY', expires_in=expiration)
        return s.dumps({'id': self.id})

    @staticmethod
    def verify_auth_token(token):
        s = Serializer('SECRET KEY')
        try:
            data = s.loads(token)
        except SignatureExpired:
            return None    # valid token, but expired
        except BadSignature:
            print("Bad signature")
            return None    # invalid token
        user = session.query(User).filter(User.id == data['id']).first()
        return user

app.py:

auth = HTTPBasicAuth('Bearer')
@auth.error_handler
def unauthorized():
    return make_response(jsonify({'error': 'Unauthorized access'}), 403)


@app.route('/v1/api/users', methods = ['POST'])
def new_user():
    username = request.json.get('username')
    password = request.json.get('password')
    if username is None or password is None:
        abort(400) # missing arguments
    if session.query(Users).filter(Users.username == username).first() is not None:
        abort(400) # existing user
    user = Users(username, password)
    user.hash_password(password)
    session.add(user)
    session.commit()
    return jsonify({ 'username': user.username }), 201, {'Location': url_for('get_user', id = user.id, _external = True)}

@app.route('/v1/api/users/<int:id>')
def get_user(id):
    user = session.query(Users.id).all()
    if not user:
        abort(400)
    return jsonify({'username': user.username})

@auth.verify_password
def verify_password(username_or_token, password):
    # first try to authenticate by token
    user = Users.verify_auth_token(username_or_token)
    if not user:
        # try to authenticate with username/password
        user = session.query(Users).filter_by(username=username_or_token).first()
        if not user or not user.verify_password(password):
            return False
    g.user = user
    return True

@app.route('/v1/api/token')
@auth.login_required
def get_auth_token():
    token = g.user.generate_auth_token(3600)
    return jsonify({'token': token.decode('ascii'), 'duration': 3600})

以下是使用cURL的终端中的用例:

 vagrant@vagrant-ubuntu-trusty-64:~/projects$ curl -u souad:souad -i -X GET http://localhost:5000/v1/api/token
    HTTP/1.0 401 UNAUTHORIZED
    Content-Type: text/html; charset=utf-8
    Content-Length: 19
    WWW-Authenticate: Bearer realm="Authentication Required"
    Server: Werkzeug/0.14.1 Python/2.7.6
    Date: Wed, 03 Oct 2018 11:30:04 GMT

API的输出:

[2018-10-03 10:01:36,253] INFO in _internal: 127.0.0.1 - - [03/Oct/2018 10:01:36] "GET /v1/api/token HTTP/1.1" 401 -

bad signature
[2018-10-03 11:30:04,710] INFO in _internal: 127.0.0.1 - - [03/Oct/2018 11:30:04] "GET /v1/api/token HTTP/1.1" 401 -

我不知道为什么会得到Exception Bad Signature

通过Flask进行身份验证并保护某些端点的最简单方法是什么?

0 个答案:

没有答案