定义Callback路由
要登录用户,您的应用程序会将浏览器重定向到 XAuth 托管的登录页面。 XAuth 然后将用户重定向回您的应用程序。您可以点击查看 XAuth 托管的认证流的工作原理。
回调路由也称为重定向地址(或重定向URI),是指用户在通过XAuth的验证后,XAuth调用您的应用的路径。回调路由对用户是不可看的,并且也不是用户的最终访问页面地址,它只是身份认证流程中信息重定向的一个接收地址。
示例
Go
您需要通过定义一个handler来创建回调路由:
http.HandleFunc("/authorization-code/callback", AuthCodeCallbackHandler)
然后您需要定义handler的工作方式。并且在此期间,通过授权码来换取access token 和 ID token
type Exchange struct {
Error string `json:"error,omitempty"`
ErrorDescription string `json:"error_description,omitempty"`
AccessToken string `json:"access_token,omitempty"`
TokenType string `json:"token_type,omitempty"`
ExpiresIn int `json:"expires_in,omitempty"`
Scope string `json:"scope,omitempty"`
IdToken string `json:"id_token,omitempty"`
}
func AuthCodeCallbackHandler(w http.ResponseWriter, r *http.Request) {
// Check the state that was returned in the query string is the same as the above state
if r.URL.Query().Get("state") != state {
fmt.Fprintln(w, "The state was not as expected")
return
}
// Make sure the code was provided
if r.URL.Query().Get("code") == "" {
fmt.Fprintln(w, "The code was not returned or is not accessible")
return
}
exchange := exchangeCode(r.URL.Query().Get("code"), r)
session, err := sessionStore.Get(r, "XAuth-hosted-login-session-store")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
_, verificationError := verifyToken(exchange.IdToken)
if verificationError != nil {
fmt.Println(verificationError)
}
if verificationError == nil {
session.Values["id_token"] = exchange.IdToken
session.Values["access_token"] = exchange.AccessToken
session.Save(r, w)
}
http.Redirect(w, r, "/", http.StatusMovedPermanently)
}
func exchangeCode(code string, r *http.Request) Exchange {
authHeader := base64.StdEncoding.EncodeToString(
[]byte(os.Getenv("CLIENT_ID") + ":" + os.Getenv("CLIENT_SECRET")))
q := r.URL.Query()
q.Add("grant_type", "authorization_code")
q.Add("code", code)
q.Add("redirect_uri", "http://localhost:8080/authorization-code/callback")
url := os.Getenv("ISSUER") + "/v1/token?" + q.Encode()
req, _ := http.NewRequest("POST", url, bytes.NewReader([]byte("")))
h := req.Header
h.Add("Authorization", "Basic "+authHeader)
h.Add("Accept", "application/json")
h.Add("Content-Type", "application/x-www-form-urlencoded")
h.Add("Connection", "close")
h.Add("Content-Length", "0")
client := &http.Client{}
resp, _ := client.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
var exchange Exchange
json.Unmarshal(body, &exchange)
return exchange
}
func verifyToken(t string) (*verifier.Jwt, error) {
tv := map[string]string{}
tv["nonce"] = nonce
tv["aud"] = os.Getenv("CLIENT_ID")
jv := verifier.JwtVerifier{
Issuer: os.Getenv("ISSUER"),
ClaimsToValidate: tv,
}
result, err := jv.New().VerifyIdToken(t)
if err != nil {
return nil, fmt.Errorf("%s", err)
}
if result != nil {
return result, nil
}
return nil, fmt.Errorf("token could not be verified: %s", "")
}
Java
待更新…
Python
待更新…
PHP
待更新…