Google登录-"access_token"对比"id_token"与“代码" [英] Google SignIn - "access_token" vs "id_token" vs "code"

查看:784
本文介绍了Google登录-"access_token"对比"id_token"与“代码"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的网站中,当使用Google登录登录时,我们曾经使用过access_token.首先,我们将用户重定向到google,用户将access_token带给我们,然后我们验证该令牌以确保该用户是实际的Google用户.

In our website we used to use access_token when logging people with Google Sign In. First, we redirect the user to google, user brings the access_token to us, and we validate that token to make sure the user is the actual Google user.

然后,我们需要Android应用程序的Google登录功能,因此我希望Android开发人员将access_token带给我们.他回答他不能.我搜索了一下,发现几乎没有关于access_token的文档.在文档中,谷歌说我要使用"id_token".

Then, we needed a Google sign-in feature for our Android app, so I wanted the Android developer to bring access_token to us. He replied he couldn't. I searched about that finding almost no documentation about access_token. In documentation, Google says me to use the "id_token".

好的,我希望开发人员将id_token带给我,并且我已经成功验证了令牌的完整性.然后,我想对网站实施相同的操作.

OK, I wanted the developer to bring me the id_token, and I have successfully verified the token's integrity. Then I wanted to implement the same for websites.

我的c#代码是:

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

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

It worked when I ran it locally, but when I tried in production, it gave an error: JWT is not yet valid

id_token是否是发送到后端并进行验证的正确方法?我也找到了另一个选项:代码.

Is id_token the correct way to send to the backend and verify? I found another option too: code.

代码类似于A/12112312 ......

Code is something like A/12112312......

Access_token就像ya29.somemorestring

Access_token is something like ya29.somemorestring

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

My question is, Which one is correct to send to the backend? By the way, I think access_token is sort of deprecated or something like that.

推荐答案

是的,您应该使用id_token.您可以使用以下方法在客户端获取id_token:

Yes, you should be using the id_token. You get the id_token on the client side using this:

var id_token = googleUser.getAuthResponse().id_token;

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

and validating it on the server side using (do in a try/catch block to catch any errors):

token = await GoogleJsonWebSignature.ValidateAsync(idToken);

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

The JWT is not yet valid error is due to the time on your server being slow. Even a few seconds slow will cause this problem. To be sure of this working all the time, you'll need to implement a custom clock which gets an accurate time from somewhere. Here's an example using 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();
        }
    }
}

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

You then pass the custom clock to the validation method.

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

请注意:每次创建该类时,这都会更新正确时间与本地机器时间之间的时差,因此,您确实想将其注册为您正在使用的任何IOC容器中的Singleton,并将引用传递给验证器代替.然后,它将每小时使用NNTP重新检查一次时间.如果您不使用IOC容器,则可以将类设为静态.

Please note: This will update the difference between the correct time and the local machine time every time the class is created, so you really want to register this as a Singleton in whatever IOC container you are using and pass the reference to the validator instead. It will then recheck the time using NNTP every hour. If you are not using an IOC Container you could make the class static.

这篇关于Google登录-"access_token"对比"id_token"与“代码"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆