用户授权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/