从OAuth请求客户端获取令牌

时间:2018-11-07 10:56:24

标签: go oauth oauth-2.0 cloudfoundry

我要从请求中获取令牌的以下代码,我传递了 API / ClientSecret / ClientID

r := fmt.Sprintf("https://tenenat.host.com/oauth/token?grant_type=client_credentials&response_type=token&client_id=%s&client_secret=%s", CI, CS)
req, err := http.NewRequest(http.MethodPost, r, nil)
req.Header.Set("accept", "application/json")
res, err := httpClient.Do(req)
if err != nil {
    fmt.Println(os.Stdout)
    var t OAuthAccessResponse
    if err := json.NewDecoder(res.Body).Decode(&t); err != nil {
        fmt.Println(os.Stdout, "could not parse JSON response: %v", err)
    }
    defer res.Body.Close()
}

运行时出现错误:

http 400错误请求。

知道我是否在请求中遗漏了什么吗?

我无法正确设置代码的格式:)

2 个答案:

答案 0 :(得分:0)

如果可以避免,则不应在URL字符串中放置敏感数据,例如客户端密码。它比使用邮件正文安全性低:例如,它可能会在日志和站点流量分析中捕获,最终与第三方共享。

相反,请使用JSON正文进行POST:

type TokenRequest struct {
    GrantType    string `json:"grant_type"`
    ResponseType string `json:"response_type"`
    ClientID     string `json:"client_id"`
    ClientSecret string `json:"client_secret"`
}
tokenReq := &TokenRequest{
    GrantType:    grantType,
    ResponseType: responseType,
    ClientID:     clientID,
    ClientSecret: clientSecret,
}
body, err := json.Marshal(tokenReq)
if err != nil {
    log.Errorf("Failed to marshal request body: %s", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(body))
if err != nil {
    log.Errorf("Failed to create request: %s", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
res, err := httpClient.Do(req)

更新

OP现在收到状态码401响应。 401是未授权的。您可能需要对API进行身份验证。例如,如果您有不记名令牌,请在发出请求之前为其添加标头:

req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearer))

答案 1 :(得分:0)

不确定您正在使用的 url,但在我的情况下,它是一个 AWS Cognito,如果请求是 json 格式,我将无法获得不记名令牌——它必须是“url 编码”。也许您的端点应该以同样的方式对待?

无论如何,这里的代码对我从 AWS Cognito 获取 client_credentials 不记名令牌有用。

// "url encode" the request data
bodyData := url.Values{}
bodyData.Set("client_id", clientID)
bodyData.Set("grant_type", "client_credentials")
bodyData.Set("scope", clientScope)
body := bodyData.Encode()
bodyBuffer := bytes.NewBuffer([]byte(body))

// create the post request
httpRequest, _ := http.NewRequest("POST", tokenEndpointURL, bodyBuffer)
httpRequest.Header.Add("Content-Type", "application/x-www-form-urlencoded")
httpRequest.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))

// post the request
httpClient := &http.Client{}
httpResponse, err := httpClient.Do(httpRequest)
if err != nil {
    fmt.Printf("error with http client do: %v", err)
    return "", err
}
defer httpResponse.Body.Close()

// read the response
responseBuffer, err := ioutil.ReadAll(httpResponse.Body)
if err != nil {
    fmt.Printf("error reading http response body: %v", err)
    return "", err
}
responseJSON := string(responseBuffer)
fmt.Printf("responseJSON: %v", responseJSON)

// unmarshal the response
type ClientCredentialsTokenResponseStruct struct {
    AccessToken string `json:"access_token"`
    TokenType   string `json:"token_type"`
    ExpiresIn   int    `json:"expires_in"`
}

var tokenResponse ClientCredentialsTokenResponseStruct
_ = json.Unmarshal([]byte(responseJSON), &tokenResponse)

不记名令牌在 tokenResponse.AccessToken 中。

祝你好运!