【发布时间】:2013-05-16 15:09:18
【问题描述】:
我正在使用 gosimple/oauth2 包来处理用户的 OAuth2 登录。我对GitHub example code 的问题为零,它可以完美运行并返回我想要的。
不过,我确实在让它与 Google 合作时遇到了问题。我已经正确地定义了我的范围(据我所见),并且我得到了一个令牌响应,但是一旦我输入它,应用程序就会在 ~ 68 行出现恐慌。
package main
import (
"bitbucket.org/gosimple/oauth2"
"flag"
"fmt"
"io"
"log"
"os"
)
var (
// Register new app at https://github.com/settings/applications and provide
// clientId (-id), clientSecret (-secret) and redirectURL (-redirect)
// as imput arguments.
clientId = flag.String("id", "", "Client ID")
clientSecret = flag.String("secret", "", "Client Secret")
redirectURL = flag.String("redirect", "http://httpbin.org/get", "Redirect URL")
scopeURL = flag.String("scope", "https://www.googleapis.com/auth/userinfo.profile", "Scope URL")
authURL = "https://accounts.google.com/o/oauth2/auth"
tokenURL = "https://www.googleapis.com/oauth2/v1/userinfo"
apiBaseURL = "https://www.googleapis.com/"
)
const startInfo = `
Register new app at https://github.com/settings/applications and provide
-id, -secret and -redirect as input arguments.
`
func main() {
flag.Parse()
if *clientId == "" || *clientSecret == "" {
fmt.Println(startInfo)
flag.Usage()
os.Exit(2)
}
// Initialize service.
service := oauth2.Service(
*clientId, *clientSecret, authURL, tokenURL)
service.RedirectURL = *redirectURL
service.Scope = *scopeURL
// Get authorization url.
aUrl := service.GetAuthorizeURL("")
fmt.Println("\n", aUrl)
// Open authorization url in default system browser.
//webbrowser.Open(url)
fmt.Printf("\nVisit URL and provide code: ")
code := ""
// Read access code from cmd.
fmt.Scanf("%s", &code)
// Get access token.
token, _ := service.GetAccessToken(code)
fmt.Println()
// Prepare resource request.
google := oauth2.Request(apiBaseURL, token.AccessToken)
google.AccessTokenInHeader = false
google.AccessTokenInHeaderScheme = "token"
//google.AccessTokenInURL = true
// Make the request.
apiEndPoint := "user"
googleUserData, err := google.Get(apiEndPoint)
if err != nil {
log.Fatal("Get:", err)
}
defer googleUserData.Body.Close()
fmt.Println("User info response:")
// Write the response to standard output.
io.Copy(os.Stdout, googleUserData.Body)
fmt.Println()
}
还有恐慌:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x2341]
这是违规行:
google := oauth2.Request(apiBaseURL, token.AccessToken)
如果能帮助我完成这项工作,我将不胜感激。请注意,代码只是来自gosimple/oauth2 repo 的修改示例代码,我正在尝试在将其与应用程序中的控制器方法包装之前调试此阶段。
完整的堆栈跟踪如下:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x2341]
goroutine 1 [running]:
main.main()
/Users/matt/Desktop/tests/google_demo.go:68 +0x341
goroutine 2 [syscall]:
goroutine 5 [runnable]:
net/http.(*persistConn).readLoop(0xc2000bd100)
/usr/local/Cellar/go/1.1/src/pkg/net/http/transport.go:761 +0x64b
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.1/src/pkg/net/http/transport.go:511 +0x574
goroutine 6 [select]:
net/http.(*persistConn).writeLoop(0xc2000bd100)
/usr/local/Cellar/go/1.1/src/pkg/net/http/transport.go:774 +0x26f
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.1/src/pkg/net/http/transport.go:512 +0x58b
...并在令牌错误上强制恐慌:
panic: No access token found, response: [78 111 116 32 70 111 117 110 100]
【问题讨论】:
-
代码中的某些对象必须为零。您能否告诉我们发生恐慌的确切行并发布该行的副本以便我们在代码中找到它?
-
你在它之前写了一个波浪号,所以我认为它可能是一个近似的行号。因此,根据您的编辑,我猜
token为零。我想知道为什么。 -
service.GetAccessToken(code)的第二个返回值是多少?您通过将其分配给_来忽略它。如果是错误,你一定要把它赋值给err,并检查它是否为nil。使用此代码:if err != nil { log.Fatal(err); }这可能会告诉您代码失败的原因。 -
好吧,那我们找错地方了。您应该弄清楚 GetAccessToken 为何返回该错误。您可能需要向库中添加一堆 fmt.Println 语句,或者以某种方式使用调试器。
-
@DavidGrayson 谢谢,感谢您的帮助。我刚刚运行了另一个 OAuth2 库 (code.google.com/p/goauth2),它按预期工作,所以这绝对是一个库错误。