2016-11-28 107 views
0

我使用Google ID tokens来登录用户到我的web服务。作为验证从Google收到的令牌的一部分,web服务会检查令牌的有效内容中的email_verified = trueemail_verified = false来自Google的ID令牌

我的部分用户signed up for a Google-account使用非Gmail非Google Apps电子邮件地址。他们确实点击了注册后Google发送给他们的电子邮件中的链接,以验证他们的电子邮件地址。

当这些用户尝试登录到我的web服务时,我在令牌的有效负载中获得email_verified = false

这是什么意思,可以/我应该忽略这在验证令牌?

+0

如果您要验证该用户有一个有效的帐户/电子邮件地址,然后没有你可能不应该忽略它。你如何实现这个登录?我还没有尝试过,但是如果email_verified作为配置文件范围的一部分返回,并且所涉及的用户没有Google+帐户,我不知道它是否会返回。 – DaImTo

+0

如果用户验证了电子邮件,那么我们应该在该声明中返回true。我们需要研究这一点。如果可能,您可以通过我的G +个人资料向我发送用户的电子邮件地址吗? – nvnagr

+0

@nvnagr我给你发了两个例子,通过G + – Rob

回答

0

有几个不同ways在其中您可以验证在服务器端的ID令牌的完整性:

  1. “手动” - 不断下载谷歌的公钥验证签名,然后每字段,包括iss之一;我在这里看到的主要优势(尽管我认为很小),可以最大限度地减少发送给Google的请求数量。
  2. “自动” - 做谷歌的端点的GET来验证此令牌 https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
  3. 使用谷歌API客户端库 - 如official one

这里是如何可以看:

private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}"; 

public ProviderUserDetails GetUserDetails(string providerToken) 
{ 
    var httpClient = new MonitoredHttpClient(); 
    var requestUri = new Uri(string.Format(GoogleApiTokenInfoUrl, providerToken)); 

    HttpResponseMessage httpResponseMessage; 
    try 
    { 
     httpResponseMessage = httpClient.GetAsync(requestUri).Result; 
    } 
    catch (Exception ex) 
    { 
     return null; 
    } 

    if (httpResponseMessage.StatusCode != HttpStatusCode.OK) 
    { 
     return null; 
    } 

    var response = httpResponseMessage.Content.ReadAsStringAsync().Result; 
    var googleApiTokenInfo = JsonConvert.DeserializeObject<GoogleApiTokenInfo>(response); 

    if (!SupportedClientsIds.Contains(googleApiTokenInfo.aud)) 
    { 
     Log.WarnFormat("Google API Token Info aud field ({0}) not containing the required client id", googleApiTokenInfo.aud); 
     return null; 
    } 

    return new ProviderUserDetails 
    { 
     Email = googleApiTokenInfo.email, 
     FirstName = googleApiTokenInfo.given_name, 
     LastName = googleApiTokenInfo.family_name, 
     Locale = googleApiTokenInfo.locale, 
     Name = googleApiTokenInfo.name, 
     ProviderUserId = googleApiTokenInfo.sub 
    }; 
} 
+0

我没有意识到第二种选择,这是一个很棒的提示!我有第一个选择。这并没有回答这个问题,因为email_verified在JWT谷歌问题中仍然是错误的,我的问题是我是否应该接受 – Rob

+0

嗨,Alexandru,tokeninfo终端在那里帮助调试。创建id_token是为了让服务器很容易验证它,而无需进行网络调用,从而增加延迟。您的建议会造成安全问题。 id令牌验证的非常重要的部分是验证令牌是否适合您的服务器(受众字段)。通过调用tokeninfo,您只会知道它是一个有效的id_token,但除非您检查了观众,否则您将创建一个安全问题。最好的选择是使用库。应该避免使用tokeninfo端点。 – nvnagr

+0

Hi @nvnagr,关于'aud'字段的验证,如果仔细观察,您可以在该页面上看到Google也明确指出了这一点 - 我也在提供的代码示例中进行了说明。 –

相关问题