Link Search Menu Expand Document

定义Callback路由

  1. 示例
    1. Go
    2. Java
    3. Python
    4. PHP

要登录用户,您的应用程序会将浏览器重定向到 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

待更新…