用户授权Google日历后,NodeJS服务将代码,AccessToken和RefreshToken 保存到存储中。

尝试使用相同的 token 通过Go编写的不同后端服务访问用户的日历。
当AccessToken有效时,数据是可访问的,但是当AccessToken过期时,在尝试访问事件时,即使该 token 有效,也无法获取config.Exchange()或config.TokenSource()给予新的 token 有效,得到错误:

错误401:无效的凭据,authError退出状态1

 tok, err := config.TokenSource(ctx, token).Token() // token is previous valid token
 if err != nil {
    log.Fatalf("Unable to retrieve token from web: %v", err)
 }

还尝试将代码交换为新 token ,但无济于事

400错误的要求
回应:{
“错误”:“invalid_grant”,
“error_description”:“验证码格式错误。”
}
    tok, err := config.Exchange(context.TODO(), in)
if err != nil {
    log.Fatalf("Unable to retrieve token from web: %v", err)
}

尝试使用calendar.NewService访问
srv, _ := calendar.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, tok)))

如何获得无需用户干预即可从其他服务脱机访问的 token ?

更新:将 token 存储到Redis-RedisJSON,但仍然不会获得新的AccessToken。这是我要传递有效 token 的完整功能。它仅在AccessToken到期之前起作用。
func GetGoogleCalendarEvents(token *oauth2.Token, userid string) *calendar.Events {
tok := &oauth2.Token{}
var config *oauth2.Config
ctx := context.Background()

b, err := ioutil.ReadFile("credentials.json")
if err != nil {
    log.Fatalf("Unable to read client secret file: %v", err)
}

config, err = google.ConfigFromJSON(b, calendar.CalendarScope) //calendar.CalendarScope)
if err != nil {
    log.Fatalf("Unable to parse client secret file to config: %v", err)
}

tok = token

if token.Expiry.Before(time.Now()) {

    tokenSource := config.TokenSource(ctx, token) //oauth2.NoContext

    newToken, err := tokenSource.Token()
    if err != nil {
        log.Fatalln(err)
    }

    if tok.AccessToken != newToken.AccessToken {
        SetAuthCredToCache(userid, tok)
        tok = newToken
        fmt.Println(newToken)
    }
}

fmt.Println(tok.Expiry, tok.Valid(), tok.Type(), tok.RefreshToken, tok.TokenType)

srv, _ := calendar.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, tok)))

t := time.Now().Format(time.RFC3339)

events, err := srv.Events.List("primary").ShowDeleted(true).
    SingleEvents(true).TimeMin(t).OrderBy("startTime").Do()

if err != nil {
    log.Fatalf("Unable to retrieve next ten of the user's events: %v", err)
}
return events

}

最佳答案

这是一个解组问题。

从Node保存 token 时,它将到期时间序列化为“expiry_date” ,而Go Token的json表示形式仅为“expiry” 。将其余对象解组到oauth2.Token对象,并向该对象添加到期时间即可解决此问题。

关于go - 无法获取Oauth2 TokenSource来刷新从存储中检索到的 token ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58534830/

10-11 16:33