MCPcopy Create free account
hub / github.com/TheThingsNetwork/lorawan-stack / HandleCallback

Method HandleCallback

pkg/web/oauthclient/callback.go:60–143  ·  view source on GitHub ↗

HandleCallback is a handler that takes the auth code and exchanges it for the access token.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

58// HandleCallback is a handler that takes the auth code and exchanges it for the
59// access token.
60func (oc *OAuthClient) HandleCallback(w http.ResponseWriter, r *http.Request) {
61 var response oauthAuthorizeResponse
62 if err := r.ParseForm(); err != nil {
63 webhandlers.Error(w, r, errParse.WithCause(err))
64 return
65 }
66 if err := oc.schemaDecoder.Decode(&response, r.Form); err != nil {
67 webhandlers.Error(w, r, errParse.WithCause(err))
68 return
69 }
70 if err := response.ValidateContext(r.Context()); err != nil {
71 webhandlers.Error(w, r, err)
72 return
73 }
74
75 stateCookie, err := oc.getStateCookie(w, r)
76 value, acErr := oc.getAuthCookie(w, r)
77 if err != nil {
78 // Running the callback without state cookie often occurs when re-running
79 // the callback after successful token exchange (e.g. using the browser's
80 // back button after logging in). If there is a valid auth cookie, we just
81 // redirect back to the client mount instead of showing an error.
82 if acErr != nil {
83 webhandlers.Error(w, r, errNoStateCookie.WithCause(acErr))
84 return
85 }
86 if value.AccessToken != "" {
87 config := oc.configFromContext(r.Context())
88 http.Redirect(w, r, config.RootURL, http.StatusFound)
89 return
90 }
91 webhandlers.Error(w, r, err)
92 return
93 }
94 if stateCookie.Secret != response.State {
95 webhandlers.Error(w, r, errInvalidState.New())
96 return
97 }
98
99 // Exchange token.
100 ctx, err := oc.withHTTPClient(r.Context())
101 if err != nil {
102 webhandlers.Error(w, r, err)
103 return
104 }
105 conf, err := oc.oauthConfig(r.Context())
106 if err != nil {
107 webhandlers.Error(w, r, err)
108 return
109 }
110 token, err := conf.Exchange(ctx, response.Code)
111 if err != nil {
112 var retrieveError *oauth2.RetrieveError
113 if stderrors.As(err, &retrieveError) {
114 var ttnErr errors.Error
115 if decErr := ttnErr.UnmarshalJSON(retrieveError.Body); decErr == nil {
116 webhandlers.Error(w, r, errExchange.WithCause(&ttnErr))
117 return

Callers

nothing calls this directly

Calls 15

ValidateContextMethod · 0.95
getStateCookieMethod · 0.95
getAuthCookieMethod · 0.95
configFromContextMethod · 0.95
withHTTPClientMethod · 0.95
UnmarshalJSONMethod · 0.95
removeStateCookieMethod · 0.95
setAuthCookieMethod · 0.95
ErrorFunction · 0.92
FromFunction · 0.92
DecodeMethod · 0.65
ContextMethod · 0.65

Tested by

no test coverage detected