InterfaceError <unprintable interfaceerror =“”object =“”>查询对象时

时间:2017-03-07 21:37:21

标签: python sqlite flask sqlalchemy

我正在使用flask和SQLAlchemy来实现OAuth2.0。在尝试查询数据库以获取Auth代码时,我收到以下错误消息(这只是Traceback的一部分。如果您需要完整的Traceback,请告诉我):

2017-03-07T21:06:23.163620+00:00 app[web.1]: InterfaceError: <unprintable InterfaceError object>
2017-03-07T21:06:23.164233+00:00 app[web.1]: 10.167.67.198 - - [07/Mar/2017 21:06:23] "POST /token HTTP/1.1" 500 -
2017-03-07T21:06:23.180516+00:00 heroku[router]: at=info method=POST path="/token" host=apiaitesting1.herokuapp.com request_id=b88e0942-90c9-4fc9-a197-fb5603533f56 fwd="66.249.88.10" dyno=web.1 connect=1ms service=23ms status=500 bytes=452

以下是我的模型。

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine


from sqlalchemy.orm import relationship
from datetime import datetime
from itsdangerous import (TimedSerializer
                          as Serializer, BadSignature, SignatureExpired)
import random
import string
from passlib.apps import custom_app_context as pwd_context

Base = declarative_base()
secret_key = "secret_key"
#''.join(random.choice(string.ascii_uppercase + string.digits) for x in xrange(32))
auth_code = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in xrange(32))

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    hotel = Column(String(250), nullable=False)
    room = Column(String(250), nullable=False)
    location = Column(String(250), nullable=False)
    password_hash = Column(String(250))
    auth_code = relationship("AuthCode", backref="room", lazy="dynamic")
    # username = Column(String(250))

    #This returns the unique id associated with the token 

    #This can be made to live for an hour. As of now it lives forever to reduce traffic from multiple requests for refreshing the token
    def generate_access_token(self):
        s = Serializer(secret_key)
        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:
                return None # invalid token
            user = User.query.get(data['id'])
            return user

    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)


class AuthCode(Base):
    __tablename__ = 'code'
    code = Column(String(250), primary_key=True, index=True)
    code_type = Column(String(250))
    client_type = Column(String(250))
    userId = Column(Integer, ForeignKey('user.id'))

    def generate_auth_code(self):
        # generate the auth code using encrption
            #Generate an index number with 16 bytes of entropy
        self.code = auth_code
        return auth_code 

    @staticmethod
    def verify_auth_code(self, auth_code):
        if auth_code == self.code:
            return useId
        else:
            return "Invalid auth code"

以下是我用来生成身份验证代码的方法。生成auth代码后,如果我查询db,如下面的代码所示,它将返回相应的对象

def createAuthCode(login_session):
    print("createAuthCode called")
    auth_code_obj = AuthCode(code_type=login_session['code_type'], client_type= login_session['client_type'], userId = login_session['room'])
    #put this in global object
    code = auth_code_obj.generate_auth_code()
    print(code)
    session.add(auth_code_obj)
    session.commit()
    mycode = session.query(AuthCode).filter_by(code=code).first()
    print (mycode)
    print ("auth code generated")
    # login_session['mycode'] = mycode
    # print(login_session['mycode'])
    return code

但是,如果我在后续请求到另一个路由点时查询数据库,它会给我上面提到的错误。下面是我再次查询数据库的方法。

注意:在调用不同的API路由点期间执行以下方法,因此与生成验证码的请求不同。

@app.route('/token', methods = ['POST'])
#@auth.login_required
def exchageToken():
    client_id = request.form.getlist('client_id')
    client_secret = request.form.getlist('client_secret')
    code = request.form.getlist('code')
    strcode = str(code)
    grant_type = request.form.getlist('grant_type')
    print(client_id[0])
    print(client_secret[0])
    print(code[0])
    print(grant_type[0])

    #Check Client id is valid. This is configured by us on google portal
    if client_id[0] != "client_id":
        return ("invalid client id.")
    #Check redirect URI is valid. This is configured by us on google portal
    if client_secret[0] != "testSecret":
        return ("invalid client secret.")
    #Check Client id is valid. This should be of type "code"
    somecode = session.query(AuthCode).filter_by(code=strcode).first()
    if grant_type[0] == "authorization_code":
        user_id = somecode.verify_auth_code(code)
        if user_id:
            mydata = {
                token_type: "bearer",
                access_token: "ACCESS_TOKEN",
                refresh_token: "REFRESH_TOKEN"
            }
            response = make_response(json.dumps(mydata, indent=4))
            return response
        else:
            return "Invalid auth code"

    elif grant_type[0] == "refresh_token":
        user_id = somecode.verify_auth_code(code)
        mydata = {
            token_type: "bearer",
            access_token: "new_access_token"
        }
        response = make_response(json.dumps(mydata, indent=4))
        return response

            #update the db with this token
            # Return Below JSON Objcet
            # {
            #   token_type: "bearer",
            #   access_token: "ACCESS_TOKEN",
            #   refresh_token: "REFRESH_TOKEN"
            #

        return True

我使用的数据库引擎是SQLite

提前致谢

1 个答案:

答案 0 :(得分:0)

想出来。参数&#34;代码&#34;通过下面的行检索返回一个列表,而不是一个字符串。

code = request.form.getlist('code')

因此设置更改&#34; strcode&#34;的值如下图所示解决了这个问题。

strcode = code[0]