如何从id_token Google Javascript API客户端(GAPI)

时间:2018-05-02 04:12:39

标签: firebase firebase-authentication google-api-js-client google-identity

我有一个带Firebase后端的SPA,并集成了Google日历访问权限。

为了能够授权用户使用他/她的Google日历,我使用gapi.auth2.authorize(params, callback)方法。 (与常规gapi.auth2.initsignIn流量相反,因为我的用户可以关联多个日历帐户)

Docsgapi.auth2.authorize

我遇到的问题:

有时从id_token返回的authorize包含电子邮件地址,有时它不会。

返回的id_token是一个长字符串,可以使用JavaScript函数在前端读取,如下所示:

function parseJwt (token) {
  let base64Url = token.split('.')[1]
  let base64 = base64Url.replace('-', '+').replace('_', '/')
  return JSON.parse(window.atob(base64))
}

当我解析id_token时,我期待一个包含email地址的对象。但有时它根本不包含email属性.... 如何使用JavaScript从此id_token中检索用户的Google日历电子邮件地址,以便将其保存到用户的firestore数据库?

解析id_token时的预期结果示例:

expected result

意外结果的示例(无电子邮件):

unexpected result

可能的原因:

我认为这可能与未退回Google G-Suite帐户电子邮件的帐户有关?那些确实返回电子邮件的是一个常规的Gmail帐户?但我不知道解决方案。

PS:
我为返回用户重新授权的流程是使用相同的gapi.auth2.authorize,但使用{prompt: 'none', login_hint: 'emailaddress'},并填写用户保存的电子邮件地址。这很好。

1 个答案:

答案 0 :(得分:0)

如果您想要使用gapi.auth2.authorize授权JavaScript客户端,但又要求用户授权使用的电子邮件地址,请务必在{>中包含email gapi.auth2.authorize(params, callback)参数!!

使用JavaScript gapi授权Google日历的正确示例:

步骤1.
包含在主HTML头中:

<script type=text/javascript src="https://apis.google.com/js/api.js" async defer=defer></script>

步骤2.
(一次)加载客户端:
window.gapi.load('client', callbackFunction)
重要提示:仅加载客户端!

步骤3.
(一次)初始化客户端以使用Calendar API 重要提示:仅包含发现文档!

let calDocs = {
    discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest']
}
window.gapi.client.init(calDocs)
    .then(_ => {
      console.log('Calendar client initialised')
    })
  })
},

步骤4.
(一次)使用gapi.auth2.authorize(params, callbackFunction)
授权gapi客户端进行API调用 重要说明:范围是带空格的字符串!在范围中包含电子邮件。请勿在此处包含发现文档!

params = {
    client_id: clientId,
    scope: 'https://www.googleapis.com/auth/calendar email',
    response_type: 'permission id_token'
}

您可以在任何带有额外参数的API调用之前重复gapi.auth2.authorize{prompt: 'none', login_hint: 'emailaddress'}来刷新用户的访问令牌。如果用户已经为您的域授权一次,则不会向用户显示任何提示。