首页 文章

Google Calendar API invalid_grant获取令牌(Golang)

提问于
浏览
0

我正在尝试检索访问令牌,以便使用Oauth2对用户进行身份验证 . 我正在使用google的HOW-TO页面上的代码来使用带有golang的Calendar API . 问题是,每当我尝试获取令牌时,谷歌都会发回:

Response: {
 "error" : "invalid_grant"
}

错误 oauth2: cannot fetch token: 400 Bad Request

正如我所说的,我正在使用谷歌的howto中的一些代码,只是略微修改以满足我的需求 .

//Somewhere...
authURL = config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)

//Somewhere else...
func getClient(ctx context.Context, config *oauth2.Config, code string) *http.Client {
    cacheFile := tokenCacheFile()

    tok, err := tokenFromFile(cacheFile)
    if err != nil {
        log.Printf("Google auth code not cached. Obtaining from the web...")
        tok, err = getTokenFromWeb(code) //This returns an error
        if err == nil {
            log.Printf("Got token!")
            saveToken("calendar-go-quickstart.json", tok)
        } else { //Prevent saving token when error
            log.Printf("Couldn't get OAUTH2 token! %s", err)
        }
    }
    return config.Client(ctx, tok)
}

错误发生在"getTokenFromWeb(code)"(如果我理解正确,代码必须是一些随机字符串,无论其值如何,它只需要在整个过程中相同) . 这是有问题的代码:

func getTokenFromWeb(code string) (*oauth2.Token, error) {
    tok, err := config.Exchange(context.Background(), code)
    return tok, err
}

执行后,我看到的是那个错误 . 尝试复制粘贴谷歌自己的示例代码时,我甚至得到了完全相同的错误!
任何的想法?我真的找不到在线解决方案 .

额外细节:使用IRIS网络框架;使用最新版本的google calendar api;使用最新版本的Golang;我已在Google Cloud Console上为OAuth2创建了客户端ID;该网站已获得可信赖的SSL证书;它侦听端口80(HTTP)和4433(HTTPS);

1 回答

  • 1

    以下是Google的示例:

    // getTokenFromWeb uses Config to request a Token.
    // It returns the retrieved Token.
    func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
      authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
      fmt.Printf("Go to the following link in your browser then type the "+
    "authorization code: \n%v\n", authURL)
    
      var code string
      if _, err := fmt.Scan(&code); err != nil {
        log.Fatalf("Unable to read authorization code %v", err)
      }
      ...
    }
    

    code 是访问显示的链接后授予用户的授权码 . fmt.Scan() 将扫描用户的输入 .

    如果您要代表其他用户行事,则必须执行与此示例类似的操作 . 如果您只是按自己的身份行事,那么您应该能够在没有代码的情况下自己进行身份验证 .

    无论哪种方式, code 都不能是随机字符串 .

相关问题