2017-08-03 191 views
0

我试图检索访问令牌,以便使用Oauth2验证用户。我主要使用google的HOW-TO页面上发现的代码来使用带有golang的Calendar API。问题是,每当我试图获得一个道理,谷歌发回这样的:Google Calendar API invalid_grant获取令牌(Golang)

Response: { 
"error" : "invalid_grant" 
} 

与错误oauth2: cannot fetch token: 400 Bad Request

正如我所说的,我使用一些代码从谷歌的HOWTO了,只是略作修改以适应我的需求。在“getTokenFromWeb(代码)”(如果我理解正确的发生

//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) 
} 

错误,代码必须有一些随机字符串,不管它的价值,它只是需要在整个过程中相同)。 这是有问题的代码:

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

执行后,我看到了什么是错误。我甚至得到完全相同的错误当试图复制粘贴谷歌自己的示例代码!
任何想法?我真的无法在网上找到解决方案。

额外的细节:使用IRIS web框架;使用最新版本的google日历api;使用最新版本的Golang;我在Google云端控制台上为OAuth2创建了一个客户端ID;该网站获得了可信的SSL证书;它侦听端口80(HTTP)和4433(HTTPS);

回答

1

下面是谷歌的例子:

// 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不能是一个随机字符串。

+0

啊,所以它被发送到客户端..但我如何检索它?我猜它是通过GET请求作为URL参数发送到web服务器的,所以我只需要在用户请求重定向后简单地读取它。我会尽快检查,我没有诚实地检查参数。 –

+0

谢谢,再次尝试后,我发现代码是作为查询参数发送的。现在我又遇到了另一个问题。 (现在编辑该问题) –

+0

编辑前,代码保持在url栏中并且每次点击 html元素时都会刷新它是否正常?它看起来很奇怪,特别是因为我没有在用户通过身份验证后与谷歌交换任何代码。不仅如此,URL路径也不会改变(我点击'Go here',但url保持为'https://myside.com?state = state-token&code = c/odeThatChangesEveryTime') –