我正在使用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
提前致谢
答案 0 :(得分:0)
想出来。参数&#34;代码&#34;通过下面的行检索返回一个列表,而不是一个字符串。
code = request.form.getlist('code')
因此设置更改&#34; strcode&#34;的值如下图所示解决了这个问题。
strcode = code[0]