Google SignIn - “access_token”vs“id_token”vs“code”

时间:2018-04-06 15:16:34

标签: oauth google-signin

在我们的网站上,我们曾经使用Google登录记录人员时使用access_token。首先,我们将用户重定向到谷歌,用户将access_token带到我们,我们验证该令牌以确保用户是真正的Google用户。

然后,我们的Android应用需要Google登录功能,因此我希望Android开发人员将access_token带给我们。他回答说他做不到。我搜索了这个发现几乎没有关于access_token的文档。在文档中,Google说我使用“id_token”。

好的,我希望开发人员给我带来id_token,并且我已经成功验证了令牌的完整性。然后我想为网站实现相同的功能。

我的c#代码是:

string googleId = GoogleJsonWebSignature.ValidateAsync(idToken).Result.Subject;

当我在本地运行它时它起作用,但是当我在生产中尝试时,它给出了一个错误: JWT尚未生效

id_token是发送到后端并验证的正确方法吗?我也找到了另一种选择:代码

代码就像A / 12112312 ......

Access_token类似于ya29.somemorestring

我的问题是,哪一个发送到后端是正确的?顺便说一句,我认为access_token有点被弃用或类似的东西。

2 个答案:

答案 0 :(得分:1)

是的,你应该使用id_token。您使用以下命令在客户端获得id_token:

var id_token = googleUser.getAuthResponse().id_token;

并使用(在try / catch块中执行以捕获任何错误)在服务器端验证它:

token = await GoogleJsonWebSignature.ValidateAsync(idToken);

JWT尚未生效错误是由于服务器上的时间很慢。即使几秒钟慢也会导致这个问题。为了确保这一点始终有效,您需要实现一个自定义时钟,从某个地方获取准确的时间。以下是使用NNTP的示例:

public class AccurateClock : Google.Apis.Util.IClock
{
    const int UpdateIntervalMinutes = 60;
    const string NntpServer = "time.nist.gov";

    private TimeSpan _timeOffset;
    private DateTime _lastChecked;

    public AccurateClock()
    {
        _timeOffset = TimeSpan.FromSeconds(0);
        _lastChecked = DateTime.MinValue;
    }

    private DateTime GetTime()
    {
        try
        {
            if (DateTime.Now.Subtract(_lastChecked).TotalMinutes >= UpdateIntervalMinutes)
            {
                // Update offset 
                var client = new TcpClient(NntpServer, 13);
                DateTime serverTime;
                using (var streamReader = new StreamReader(client.GetStream()))
                {
                    var response = streamReader.ReadToEnd();
                    var utcDateTimeString = response.Substring(7, 17);
                    serverTime = DateTime.ParseExact(utcDateTimeString, "yy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
                }
                _timeOffset = DateTime.UtcNow.Subtract(serverTime);
                _lastChecked = DateTime.Now;
            }
            var accurateTime = DateTime.UtcNow.Subtract(_timeOffset);
            return accurateTime;
        }
        catch (Exception ex)
        {
            return DateTime.UtcNow;
        }

    }

    public DateTime Now
    {
        get
        {
            return GetTime().ToLocalTime();
        }
    }

    public DateTime UtcNow
    {
        get
        {

            return GetTime();
        }
    }
}

然后将自定义时钟传递给验证方法。

token = await GoogleJsonWebSignature.ValidateAsync(idToken, new AccurateClock());

请注意:这将在每次创建类时更新正确时间和本地计算机时间之间的差异,因此您确实希望在您使用的任何IOC容器中将其注册为Singleton并将引用传递给验证器而不是。然后它将每小时使用NNTP重新检查时间。如果您没有使用IOC容器,则可以使该类保持静态。

答案 1 :(得分:0)

id_token 是一个 JWT 令牌,您可以验证和提取诸如“电子邮件”、“姓名”等信息。这实际上是您在常规情况下所需要的。

codeaccess_token 是当用户当前未使用您的应用但您的应用想要代表他们执行任何操作时的流程的一部分。 Google 称之为离线访问 https://developers.google.com/identity/sign-in/web/server-side-flow