go – oauth2无法获取令牌:错误的请求

huangapple go评论79阅读模式
英文:

go - oauth2 cannot fetch token: bad request

问题

我编写了一个回调处理程序来使用Google帐号登录:

func GoogleCallbackHandler(w http.ResponseWriter, r *http.Request) {
    conf := &oauth2.Config{
        ClientID:     "700740834863-m4om9r91htn19htq2b6a05fu6vu4j7i5.apps.googleusercontent.com",
        ClientSecret: "...-rB",
        RedirectURL:  "http://localhost:3000/auth/google/callback",
        Scopes:       []string{"profile"},
        Endpoint:     google.Endpoint,
    }

    fmt.Println(conf.AuthCodeURL("state"))

    code := r.URL.Query().Get("code")

    token, err := conf.Exchange(oauth2.NoContext, code)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    client := conf.Client(oauth2.NoContext, token)
    resp, err := client.Get("https://www.googleapis.com/userinfo/v2/me")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    raw, err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    var profile map[string]interface{}
    if err := json.Unmarshal(raw, &profile); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    session, _ := util.GlobalSessions.SessionStart(w, r)
    defer session.SessionRelease(w)

    session.Set("id_token", token.Extra("id_token"))
    session.Set("access_token", token.AccessToken)
    session.Set("profile", profile)

    // // Redirect to logged in page

    http.Redirect(w, r, "/user", http.StatusMovedPermanently)
}

main函数中,我为处理程序提供服务:

http.HandleFunc("/", route.IndexHandler)
http.HandleFunc("/auth/google/", route.GoogleCallbackHandler)
http.Handle("/user", negroni.New(
    negroni.HandlerFunc(route.IsAuthenticated),
    negroni.Wrap(http.HandlerFunc(route.UserHandler)),
))

我遇到了与我之前问题相同的问题:
https://stackoverflow.com/questions/35860811/oauth2-cannot-fetch-token-bad-request/

oauth2: cannot fetch token: 400 Bad Request
Response: {
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}

在上次提问后,我使用上述代码成功修复了它,并成功访问和获取数据,但昨晚它突然再次出现此错误,我不明白为什么在过去几天完全相同的代码工作后它不再起作用。

我如何从AuthCodeURL中获取code?有没有办法在不重定向到任何其他处理程序的情况下获取用于交换的代码?我希望在这个处理程序中处理所有事情。

英文:

I write a callback handler to login with Google account:

func GoogleCallbackHandler(w http.ResponseWriter, r *http.Request) {
conf:=&oauth2.Config{
ClientID:"700740834863-m4om9r91htn19htq2b6a05fu6vu4j7i5.apps.googleusercontent.com",
ClientSecret:"...-rB",
RedirectURL:"http://localhost:3000/auth/google/callback",
Scopes:[]string{"profile"},
Endpoint:google.Endpoint,
}
fmt.Println(conf.AuthCodeURL("state"))
code := r.URL.Query().Get("code")
token, err := conf.Exchange(oauth2.NoContext, code)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
client := conf.Client(oauth2.NoContext, token)
resp, err := client.Get("https://www.googleapis.com/userinfo/v2/me")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
raw, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var profile map[string]interface{}
if err := json.Unmarshal(raw, &profile); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session, _ := util.GlobalSessions.SessionStart(w, r)
defer session.SessionRelease(w)
session.Set("id_token", token.Extra("id_token"))
session.Set("access_token", token.AccessToken)
session.Set("profile", profile)
// // Redirect to logged in page
http.Redirect(w, r, "/user", http.StatusMovedPermanently)
}

In main, I serve handlers

http.HandleFunc("/",route.IndexHandler)
http.HandleFunc("/auth/google/",route.GoogleCallbackHandler)
http.Handle("/user",negroni.New(
negroni.HandlerFunc(route.IsAuthenticated),
negroni.Wrap(http.HandlerFunc(route.UserHandler)),
))

I encounter the same problem I got with my old question:
https://stackoverflow.com/questions/35860811/oauth2-cannot-fetch-token-bad-request/

oauth2: cannot fetch token: 400 Bad Request
Response: {
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
}

After I asked this question last time, I managed to fix it with my above code, accessing and getting data successfully, but last night it suddenly got this error again, and I don't get why it no longer works after last few days working with totally same code

How can I get the code from AuthCodeURL? Is there any way to get the code for exchanging without redirecting to any other handler? I want to handle all things in just one this handler

答案1

得分: 0

我可以通过添加一个处理程序来解决这个问题。

var (
    conf *oauth2.Config
)

func GoogleCallbackHandler(w http.ResponseWriter, r *http.Request) {
    conf = &oauth2.Config{
        ClientID:     "700740834863-m4om9r91htn19htq2b6a05fu6vu4j7i5.apps.googleusercontent.com",
        ClientSecret: "...-rB",
        RedirectURL:  "http://localhost:3000/auth/google/callback",
        Scopes:       []string{"profile"},
        Endpoint:     google.Endpoint,
    }

    http.Redirect(w, r, conf.AuthCodeURL("state"), http.StatusMovedPermanently)
}

func GoogleLoginHandler(w http.ResponseWriter, r *http.Request) {
    code := r.URL.Query().Get("code")

    token, err := conf.Exchange(oauth2.NoContext, code)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    client := conf.Client(oauth2.NoContext, token)
    resp, err := client.Get("https://www.googleapis.com/userinfo/v2/me")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    raw, err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    var profile map[string]interface{}
    if err := json.Unmarshal(raw, &profile); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    session, _ := util.GlobalSessions.SessionStart(w, r)
    defer session.SessionRelease(w)

    session.Set("id_token", token.Extra("id_token"))
    session.Set("access_token", token.AccessToken)
    session.Set("profile", profile)

    http.Redirect(w, r, "/user", http.StatusMovedPermanently)
}
英文:

I can solve it by adding one more handler

var (
conf *oauth2.Config
)
func GoogleCallbackHandler(w http.ResponseWriter, r *http.Request) {
conf=&oauth2.Config{
ClientID:"700740834863-m4om9r91htn19htq2b6a05fu6vu4j7i5.apps.googleusercontent.com",
ClientSecret:"...-rB",
RedirectURL:"http://localhost:3000/auth/google/callback",
Scopes:[]string{"profile"},
Endpoint:google.Endpoint,
}
http.Redirect(w, r, conf.AuthCodeURL("state"), http.StatusMovedPermanently)
}
func GoogleLoginHandler(w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code")
token, err := conf.Exchange(oauth2.NoContext, code)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
client := conf.Client(oauth2.NoContext, token)
resp, err := client.Get("https://www.googleapis.com/userinfo/v2/me")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
raw, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var profile map[string]interface{}
if err := json.Unmarshal(raw, &profile); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session, _ := util.GlobalSessions.SessionStart(w, r)
defer session.SessionRelease(w)
session.Set("id_token", token.Extra("id_token"))
session.Set("access_token", token.AccessToken)
session.Set("profile", profile)
http.Redirect(w, r, "/user", http.StatusMovedPermanently)
}

huangapple
  • 本文由 发表于 2016年3月15日 12:10:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/36002536.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定