Golang如何从服务器获取Token

Golang如何从服务器获取Token 使用Postman并按照截图中的配置,我能够从服务器获取令牌。 如何使用Golang代码实现这一点?

image

2 回复

我发现 Postman 在最右侧有一个“代码片段”生成器,可以生成 Go 代码。

image

package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://....../oauth2/token"
  method := "POST"

  payload := strings.NewReader("tenant_id=xxxx&client_id=xxxx&client_secret=xxxx&grant_type=xxxx")

 	req, _ := http.NewRequest(method, url, payload)

	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := ioutil.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))
}

更多关于Golang如何从服务器获取Token的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中从服务器获取Token,通常需要发送HTTP POST请求并处理JSON响应。以下是基于常见OAuth2令牌端点实现的示例代码:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "time"
)

// TokenResponse 定义令牌响应的结构
type TokenResponse struct {
    AccessToken  string `json:"access_token"`
    TokenType    string `json:"token_type"`
    ExpiresIn    int    `json:"expires_in"`
    RefreshToken string `json:"refresh_token,omitempty"`
    Scope        string `json:"scope,omitempty"`
}

// GetToken 从服务器获取访问令牌
func GetToken(tokenURL, clientID, clientSecret string) (*TokenResponse, error) {
    // 准备请求体数据
    data := map[string]string{
        "grant_type":    "client_credentials",
        "client_id":     clientID,
        "client_secret": clientSecret,
        "scope":         "api",
    }
    
    jsonData, err := json.Marshal(data)
    if err != nil {
        return nil, fmt.Errorf("序列化请求数据失败: %v", err)
    }
    
    // 创建HTTP请求
    req, err := http.NewRequest("POST", tokenURL, bytes.NewBuffer(jsonData))
    if err != nil {
        return nil, fmt.Errorf("创建请求失败: %v", err)
    }
    
    // 设置请求头
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Accept", "application/json")
    
    // 发送请求
    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("发送请求失败: %v", err)
    }
    defer resp.Body.Close()
    
    // 读取响应
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("读取响应失败: %v", err)
    }
    
    // 检查HTTP状态码
    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("服务器返回错误状态码: %d, 响应: %s", 
            resp.StatusCode, string(body))
    }
    
    // 解析JSON响应
    var tokenResp TokenResponse
    if err := json.Unmarshal(body, &tokenResp); err != nil {
        return nil, fmt.Errorf("解析JSON响应失败: %v", err)
    }
    
    return &tokenResp, nil
}

// 使用示例
func main() {
    tokenURL := "https://your-server.com/oauth/token"
    clientID := "your-client-id"
    clientSecret := "your-client-secret"
    
    token, err := GetToken(tokenURL, clientID, clientSecret)
    if err != nil {
        fmt.Printf("获取令牌失败: %v\n", err)
        return
    }
    
    fmt.Printf("访问令牌: %s\n", token.AccessToken)
    fmt.Printf("令牌类型: %s\n", token.TokenType)
    fmt.Printf("过期时间: %d秒\n", token.ExpiresIn)
    
    // 使用令牌进行后续API调用
    // apiURL := "https://your-server.com/api/resource"
    // req, _ := http.NewRequest("GET", apiURL, nil)
    // req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token.AccessToken))
}

如果服务器要求使用application/x-www-form-urlencoded格式,可以使用以下替代方案:

func GetTokenFormEncoded(tokenURL, clientID, clientSecret string) (*TokenResponse, error) {
    // 准备表单数据
    formData := fmt.Sprintf(
        "grant_type=client_credentials&client_id=%s&client_secret=%s&scope=api",
        clientID, clientSecret,
    )
    
    req, err := http.NewRequest("POST", tokenURL, bytes.NewBufferString(formData))
    if err != nil {
        return nil, err
    }
    
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    
    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    
    var tokenResp TokenResponse
    if err := json.Unmarshal(body, &tokenResp); err != nil {
        return nil, err
    }
    
    return &tokenResp, nil
}

对于需要基本认证的情况:

func GetTokenWithBasicAuth(tokenURL, clientID, clientSecret string) (*TokenResponse, error) {
    data := map[string]string{
        "grant_type": "client_credentials",
        "scope":      "api",
    }
    
    jsonData, _ := json.Marshal(data)
    
    req, _ := http.NewRequest("POST", tokenURL, bytes.NewBuffer(jsonData))
    req.SetBasicAuth(clientID, clientSecret)
    req.Header.Set("Content-Type", "application/json")
    
    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    body, _ := io.ReadAll(resp.Body)
    
    var tokenResp TokenResponse
    json.Unmarshal(body, &tokenResp)
    
    return &tokenResp, nil
}

这些示例涵盖了从服务器获取Token的常见场景,可以根据实际API要求调整请求参数和头部信息。

回到顶部