Files
kirogo/auth/oidc.go

101 lines
2.6 KiB
Go

package auth
import (
"bytes"
"encoding/json"
"fmt"
"io"
"kiro-api-proxy/config"
"net/http"
"time"
)
// RefreshToken 刷新 access token
func RefreshToken(account *config.Account) (string, string, int64, error) {
if account.AuthMethod == "social" {
return refreshSocialToken(account.RefreshToken)
}
return refreshOIDCToken(account.RefreshToken, account.ClientID, account.ClientSecret, account.Region)
}
// refreshOIDCToken IdC/Builder ID token 刷新
func refreshOIDCToken(refreshToken, clientID, clientSecret, region string) (string, string, int64, error) {
if region == "" {
region = "us-east-1"
}
url := fmt.Sprintf("https://oidc.%s.amazonaws.com/token", region)
payload := map[string]string{
"clientId": clientID,
"clientSecret": clientSecret,
"refreshToken": refreshToken,
"grantType": "refresh_token",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return "", "", 0, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
respBody, _ := io.ReadAll(resp.Body)
return "", "", 0, fmt.Errorf("refresh failed: %d %s", resp.StatusCode, string(respBody))
}
var result struct {
AccessToken string `json:"accessToken"`
RefreshToken string `json:"refreshToken"`
ExpiresIn int `json:"expiresIn"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", "", 0, err
}
expiresAt := time.Now().Unix() + int64(result.ExpiresIn)
return result.AccessToken, result.RefreshToken, expiresAt, nil
}
// refreshSocialToken Social (GitHub/Google) token 刷新
func refreshSocialToken(refreshToken string) (string, string, int64, error) {
url := "https://prod.us-east-1.auth.desktop.kiro.dev/refreshToken"
payload := map[string]string{
"refreshToken": refreshToken,
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := httpClient.Do(req)
if err != nil {
return "", "", 0, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
respBody, _ := io.ReadAll(resp.Body)
return "", "", 0, fmt.Errorf("refresh failed: %d %s", resp.StatusCode, string(respBody))
}
var result struct {
AccessToken string `json:"accessToken"`
RefreshToken string `json:"refreshToken"`
ExpiresIn int `json:"expiresIn"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", "", 0, err
}
expiresAt := time.Now().Unix() + int64(result.ExpiresIn)
return result.AccessToken, result.RefreshToken, expiresAt, nil
}