多个作用域值到oauth2

66

我试图提交多个作用域值以允许我的应用程序使用一些Google服务...

我尝试使用两个输入字段。

<input type="hidden" name="scope" value="https://www.googleapis.com/auth/calendar" />  
<input type="hidden" name="scope" value="https://www.googleapis.com/auth/userinfo.email" />

只有一个带有 + 分隔符的输入字段

<input type="hidden" name="scope" value="https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/userinfo.email" />  

当我只发送一个作用域的表单时,它可以工作。 否则,当我发送多个作用域值的表单时,谷歌会将我重定向,并显示以下错误描述:

http://localhost:49972/redirect.aspx#error=invalid_request&error_description=OAuth+2+parameters+can+only+have+a+single+value:+scope&error_uri=http://code.google.com/apis/accounts/docs/OAuth2.html 

在Google的OAuth2入门中,formingtheurl支持两种范围值。

这是我的代码:

  <form id="form1" method="post" action="https://accounts.google.com/o/oauth2/auth?" >
    <div>
        <input type="hidden" name="response_type" value="code" />
        <input type="hidden" name="client_id" value="my client id" />
        <input type="hidden" name="redirect_uri" value="http://localhost:49972/redirect.aspx" />
        <input type="hidden" name="scope" value="https://www.googleapis.com/auth/calendar" />
        <input type="hidden" name="scope" value="https://www.googleapis.com/auth/userinfo.email" />
        
        <input type="hidden" name="state" value="/profile" />
        <input type="submit" value="go" />
    </div>
    </form>
3个回答

126

当你将它们组合成一个单一字段时,你已经走在了正确的道路上。请求中只应该有一个作用域参数,并且值之间用空格分隔。如果你像这样放在表单中,浏览器会自动为你编码空格。

<input type="hidden" name="scope" value="https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email" />

我明天才能拿到我的代码,但即使看起来有些奇怪,还是谢谢你。 - Christophe Debove
3
目前在2017年,您应该使用value="https://www.googleapis.com/auth/calendar email" - Ivan Borshchov
11
对于好奇的人,RFC 6749, Section 3.3scope参数定义为“作用域参数的值表示为一串以空格分隔、区分大小写的字符串列表”。 - davidjb

4
除了Steve Bazyl的回答外,当为同一Google服务应用多个作用域时,作用域的顺序似乎很重要。例如,这个字符串按预期工作:
"https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.metadata.readonly"

而这个对我不起作用:

"https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive"

虽然我在文档中没有找到相关信息。


1

为了清晰起见,您可以将所有作用域放在一个数组中:

 const scopes = [
    'openid',
    'https://www.googleapis.com/auth/userinfo.profile',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/gmail.readonly',
  ]

  const scope = scopes.join(' ')

  console.log(scope)
  // openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/gmail.readonly


  const redirectUri = 'http://localhost:3000'
  const link = `https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=${scope}&response_type=code&client_id=${GOOGLE.clientId}&redirect_uri=${redirectUri}&state=authGoogle`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接