Python lepture/Authlib客户端不适用于OAuth2授权代码流

Python lepture/Authlib客户端不适用于OAuth2授权代码流,python,flask,oauth,oauth-2.0,authlib,Python,Flask,Oauth,Oauth 2.0,Authlib,我正在尝试使用实现OAuth2提供程序和客户端。我按照文档编写提供程序,它似乎是正确的,但是客户端在被重定向到身份验证页面并成功确认访问资源后,我得到了以下错误:{error:invalid_grant}。不幸的是,我找不到原因 这是我的代码: models.py 从小马进口* 从authlib.oauth2.rfc6749导入ClientMixin db=数据库 类Userdb.Entity: id=PrimaryKeyint,auto=True name=Requiredstr 用户名=Re

我正在尝试使用实现OAuth2提供程序和客户端。我按照文档编写提供程序,它似乎是正确的,但是客户端在被重定向到身份验证页面并成功确认访问资源后,我得到了以下错误:{error:invalid_grant}。不幸的是,我找不到原因

这是我的代码:

models.py

从小马进口* 从authlib.oauth2.rfc6749导入ClientMixin db=数据库 类Userdb.Entity: id=PrimaryKeyint,auto=True name=Requiredstr 用户名=Requiredstr 密码=Requiredstr clients=SetClient tokens=SetToken def get_user_idself: 返回self.id def get_usernameself: 返回self.name 类Clientdb.Entity,ClientMixin: id=PrimaryKeyint,auto=True name=Requiredstr 客户id=Requiredstr 客户_secret=Requiredstr 重定向\u url=Requiredstr users=SetUser tokens=SetToken def check_redirect_uriself,redirect_uri: 打印客户端::检查\u重定向\u uri:,重定向\u uri 返回真值 def检查\响应\类型自身,响应\类型: 打印客户端::检查\响应\类型:,响应\类型 返回响应\输入[授权\代码、代码、密码] 授权令牌 类Tokendb.Entity: id=PrimaryKeyint,auto=True 值=Requiredstr 用户=所需用户 客户端=所需客户端 scope=Optionalstr @db_会话 def创建新用户名、用户名、密码: user=Username=name,Username=Username,password=password 犯罪 @db_会话 def创建新客户端名称、客户端id、客户端机密、重定向url: client=Clientname=name,client\u id=client\u id,client\u secret=client\u secret,redirect\u url=redirect\u url 犯罪 从authlib.oauth2.rfc6749导入授权 从authlib.common.security导入生成\u令牌 类AuthorizationCodeGrantgrants.AuthorizationCodeGrant: @db_会话 def创建\授权\代码自身、客户端、授权\用户、请求: 代码=生成\u标记48 token=Tokenvalue=token,user=user[intgrant\u user.get\u user\u id], client=client[intclient.client\u id],scope=request.scope 犯罪 打印授权代码授予::创建授权代码:令牌:,令牌 返回码 def解析\授权\代码自身、代码、客户端: 打印授权代码授权::解析授权代码 token=token.selectlambda t:t.value==code和t.client\u id==client.client\u id.first 返回令牌 def delete_authorization_codeself,authorization_code: 打印授权代码授权::删除自动化代码:,授权代码。用户id def认证\用户自身,授权\代码: 打印用户身份验证 返回用户[未授权\代码.用户\ id] db.bindprovider='sqlite',filename='database.sqlite',create_db=True db.generate\u mappingcreate\u tables=True 设置_sql_debugTrue server.py

app=Flask\uuuu name\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu @db_会话 def查询\u客户端\u id: 打印查询客户端id,客户端id client=client.selectlambda c:c.client\u id==client\u id.first 返回客户端 @db_会话 def保存令牌令牌数据,请求: 如果请求。用户: user\u id=request.user.get\u user\u id 打印用户id,用户id 其他: user\u id=request.client.user\u id 打印用户id,用户id client=client[intrequest.client.client\u id] 用户=用户[intuser\u id] 令牌=令牌用户=用户,客户端=客户端 犯罪 服务器=授权服务器 query\u client=query\u client, 保存令牌=保存令牌, AuthorizationCodeGrant defindo em models.py server.register\u grantAuthorizationCodeGrant 从authlib.flask.oauth2导入ResourceProtector require_oauth=ResourceProtector def当前用户: 如果会话中有“id”: uid=会话['id'] 尝试: 返回用户[intuid] 除: 一无所获 一无所获 @app.route'/',methods=['GET','POST'] @db_会话 def索引: 如果会话['id']: 用户=当前用户 返回呈现模板'user.html',user=user 返回渲染模板'index.html' @app.route'/login',methods=['GET','POST'] @db_会话 def登录: 如果request.method==“GET”: 如果会话['id']: 用户=当前用户 返回呈现模板'user.html',user=user 返回呈现模板'login.html' 其他: 用户名=请求。表单['username'] user=user.selectlambda c:c.username==username.first 如果用户: 会话['id']=user.id 返回呈现模板'user.html',user=user 其他: 返回render_模板'error.html',msg=Usuario nao encontrado @app.route'/newlogin',methods=['GET','POST'] def create_登录: 如果request.method==“GET”: 返回呈现模板'newlogin.html' 其他: name=re quest.form['name'] 用户名=请求。表单['username'] 密码=请求。表单['password'] 创建新的用户名、用户名、密码 返回重定向/ @app.route'/logout',methods=['GET','POST'] def注销: 会话['id']=无 返回重定向“/” @app.route'/clients',methods=['GET','POST'] @db_会话 def客户端: 如果request.method==“POST”: name=请求。表单['name'] 客户id=gen\u salt24 客户机密=gen\u salt48 redirect\u url=request.form['redirecturl'] 创建新的客户端名称、客户端id、客户端密码、重定向url=重定向url clients=Client.select 返回呈现模板'clients.html',clients=clients @app.route'/oauth/authorize',方法=['GET','POST'] @db_会话 def授权: 用户=当前用户 如果request.method==“GET”: 尝试: 授权=服务器。验证\u同意\u请求结束\u用户=用户 打印服务器:/authorize:grant: pprintvarsgrant 除OAuth2Error作为错误外: 返回错误 返回呈现模板'authorize.html',user=user,grant=grant 如果不是request.form中的用户和“用户名”: username=request.form.get'username' user=user.selectlambda u:u.username==username.first 如有要求,请填写表格['confirm']: 授予用户=用户 其他: 授予用户=无 打印服务器:/authorize:grant\u user:,grant\u user 返回服务器。创建\授权\响应者\用户=授权\用户 @app.route'/oauth/token',methods=['GET','POST'] def发行令牌: return server.create_token_响应 @app.route'/user/profile' @需要_oauthprofile def get_配置文件: 返回当前用户的JSONIFYU 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 导入操作系统 os.environ['OAUTHLIB\u unsecure\u TRANSPORT']=“true” os.environ['AUTHLIB\u unsecure\u TRANSPORT']='1' app.debug=True app.secret_key='development' server.init_appapp app.run client.py

app=烧瓶名称__ oauth=OAuthapp client=oauth.register name='ecl-app1', 客户_id='wKbpjHNvSSeirBO9SzYdWOg4', 客户_secret='1SNDG8hxpNjP2rrlapVAPy8d9CHdVQ8Kzd4NqHydV7VdIrv7', 访问\u令牌\u url=http://localhost:5000/oauth/access_token', 授权http://localhost:5000/oauth/authorize', api_base_url='1〕http://localhost:5000/', 授予\u type='code', client_kwargs={'scope':'profile'}, @应用程序路径“/” def索引: 为“授权”重定向\u uri=url\u,\u external=True 打印应用程序客户端:索引:重定向\u uri:,重定向\u uri resp=client.authorize\u redirect\u uri 打印应用程序客户端:索引:authorize\u redirect:,resp 打印响应状态 打印响应标题 printresp.get_数据 返回client.authorize\u redirect\u uri @app.route'/authorize' def授权: 打印应用程序客户端:授权: 令牌=client.authorize\u access\u令牌 您可以将令牌保存到数据库中 profile=client.get'/user' 返回ok 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 导入操作系统 os.environ['OAUTHLIB\u unsecure\u TRANSPORT']=“true” os.environ['AUTHLIB\u unsecure\u TRANSPORT']='1' app.debug=True app.secret_key='development' app.runport=9000
我不知道全部密码。但是从您提供的信息来看,我猜这是因为没有将response_type传递到POST请求中

确保您的HTML模板包含请求的响应类型字段,如果URL中有响应类型,也可以

请使用以下选项检查您的代码:

print(request.args)
print(request.form)

确保响应类型在其中。

无效授权显示在哪一部分?它是POST/oauth/authorize吗?此外,您能否提供您的操作系统、Python环境和Authlib版本?是的,在authorize方法中,返回服务器中会显示无效的授权。create\u authorization\u responsegrant\u user=grant\u user。我正在使用Ubuntu,Python2.7。如果它有效,你可以将答案标记为已解决。是的!我在POST请求中找不到响应类型。@EduardoLopes然后,确保表单中有响应类型。