问题描述
我正在尝试将Google日历实施到我们的Web项目中。搜索并尝试了几乎所有提包之后的技巧之后,在用户同意访问日历后,我无法获得刷新令牌。我想在我的前端(访问令牌和刷新令牌)获取用户的日历访问权限,并为它提供后端(python)以便稍后刷新访问令牌。 在尝试了几种可用的解决方案之后,我正在使用这一解决方案- 在html中-
<script src="https://apis.google.com/js/client.js"></script>
在javascript按钮上单击-
gapi.auth.authorize({
client_id: xxx.apps.googleusercontent.com,client_secret: 'XYZ',scope: "https://www.googleapis.com/auth/calendar",immediate: false,response_type: 'code token',access_type:'offline',prompt:'consent'
},handleAuthResult);
由此我可以得到以下答复-
{
"token_type": "Bearer","access_token": "XXX","scope": "email profile openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/calendar","login_hint": "XXX","expires_in": "3559","id_token": "XXX","session_state": null,"expires_at": "1597689877","code": "4/3XXXXX","status": {
"signed_in": true,"method": "PROMPT","google_logged_in": true
},"g-oauth-window": null,"client_id": "XXX.apps.googleusercontent.com","cookie_policy": "single_host_origin","response_type": "code token","authuser": "2","issued_at": "1597686278"
}
但是仍然没有刷新令牌的迹象,我尝试通过此api交换访问令牌和ID令牌的代码-
let request_params = JSON.stringify({
code: '4/3XXXXX',client_id: 'XXX.apps.googleusercontent.com',client_secret: 'XXX',redirect_uri: 'http://localhost:5000',grant_type: 'authorization_code'
});
$.ajax({
url: 'https://oauth2.googleapis.com/token',type: 'POST',data: request_params,headers: {
'Content-type': 'application/x-www-form-urlencoded'
},contentType: "application/x-www-form-urlencoded",success: (res) => {
console.log(res,'tokens')
},error: (error) => {
console.log('An error occurred',error)
}
});
但这也给出了无效的grant_type错误。 非常感谢任何帮助。 另外,请告诉我是否有其他方法可以使用服务器直接重定向以获取身份验证而不是JavaScript。
解决方法
借助python中的OAuth2WebServerFlow,我能够弄清楚这一点。 这是我遵循的过程-
- 创建流实例,例如-
flow = OAuth2WebServerFlow(client_id='XXX',client_secret='XXX',scope='https://www.googleapis.com/auth/calendar',redirect_uri='your_redirect_url',access_type='offline',prompt='consent')
-
重定向到-
获得的授权URLauth_uri = flow.step1_get_authorize_url()
-
身份验证后,用户将被重定向到您提供的redirect_url以及作为参数的代码。
-
将此代码传递给后端,以使用-
credentials = flow.step2_exchange(code)
获得访问和刷新令牌。这里的流程将与使用步骤1生成的流程实例相同,并且凭据将具有令牌。
注意:如果您已经生成了有效的刷新令牌并尝试再次授予访问权限,则Google不提供令牌,并且step2_exchange会生成无效的授权错误。