本文档说明如何在其他系统中调用4A统一API网关服务。
| 环境 | 地址 |
|---|---|
| 本地开发 | http://localhost:28004 |
| 测试环境 | http://localhost:28004 |
| 线上环境 | https://aqai.shudaodsj.com:22000/auth |
获取SSO单点登录票据。
import requests
# 本地/测试环境
url = "http://localhost:28004/api/ticket/get"
# 线上环境
# url = "https://aqai.shudaodsj.com:22000/auth/api/ticket/get"
response = requests.post(url, json={
"mobile": "17800000001", # 可选,不传使用默认值
"app_code": "SDJD_AQAI" # 可选,不传使用默认值
})
result = response.json()
# 返回: {"retCode": "1000", "ssoTicket": "..."}
解析票据获取用户信息。
url = "http://localhost:28004/api/ticket/analyze"
response = requests.post(url, json={
"ticket_data": "oXlMiYSOLhJAYP3Qo7Zwps..." # 从票据获取接口得到的ssoTicket
})
result = response.json()
# 返回: {"retCode": "1000", "token": "...", "userInfo": {...}}
一步完成票据解析和JWT Token生成。
url = "http://localhost:28004/api/ticket/process"
response = requests.post(url, json={
"ticket_data": "oXlMiYSOLhJAYP3Qo7Zwps..."
})
result = response.json()
# 返回:
# {
# "retCode": "1000",
# "message": "处理成功",
# "ticket_token": "...",
# "username": "张三",
# "refresh_token": "eyJ...",
# "token_type": "bearer",
# "expires_in": 43200
# }
根据用户信息生成JWT Token。
url = "http://localhost:28004/auth/tokens"
response = requests.post(url, json={
"accountID": "user001",
"name": "张三",
"userCode": "N1234567",
"contactNumber": "13800138000"
})
result = response.json()
# 返回:
# {
# "access_token": "eyJ...",
# "refresh_token": "eyJ...",
# "token_type": "bearer",
# "expires_in": 43200
# }
验证Token是否有效。
url = "http://localhost:28004/auth/verify"
response = requests.post(url, json={
"token": "eyJ..."
})
result = response.json()
# 返回:
# {
# "valid": true,
# "token_type": "refresh",
# "accountID": "user001",
# "name": "张三",
# "userCode": "N1234567",
# "contactNumber": "13800138000",
# "exp": 1702857600
# }
分页查询从账号。
url = "http://localhost:28004/api/account/query"
response = requests.post(url, json={
"cur_page": 1,
"page_size": 10,
"user_code": "N1234567", # 可选
"user_name": "张三", # 可选,支持模糊匹配
"org_code": "NG5596477" # 可选
})
result = response.json()
# 返回: {"success": true, "data": [...], "recordsTotal": 100, ...}
url = "http://localhost:28004/api/account/add"
response = requests.post(url, json={
"user_code": "N1234567",
"org_code": "NG5596477",
"org_name": "蜀道投资集团有限责任公司"
})
url = "http://localhost:28004/api/account/modify"
response = requests.post(url, json={
"account_id": "aizscs001",
"org_code": "NG5596477"
})
url = "http://localhost:28004/api/account/delete"
response = requests.post(url, json={
"account_id": "aizscs001"
})
线上环境通过Nginx代理,路径前缀为 /auth:
# 本地/测试
base_url = "http://localhost:28004"
# 线上
base_url = "https://aqai.shudaodsj.com:22000/auth"
# 调用示例
ticket_url = f"{base_url}/api/ticket/get"
auth_url = f"{base_url}/auth/tokens"
所有接口返回统一格式:
// 成功
{"retCode": "1000", "msg": "成功", ...}
// 失败
{"detail": "错误信息"}
HTTP状态码:
response = requests.get("http://localhost:28004/health")
# 返回: {"status": "healthy", "service": "unified-api-gateway"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const baseURL = "http://localhost:28004" // 线上: https://aqai.shudaodsj.com:22000/auth
type TicketRequest struct {
Mobile string `json:"mobile,omitempty"`
AppCode string `json:"app_code,omitempty"`
}
type TicketResponse struct {
RetCode string `json:"retCode"`
SSOTicket string `json:"ssoTicket"`
}
func GetTicket() (*TicketResponse, error) {
reqBody, _ := json.Marshal(TicketRequest{})
resp, err := http.Post(baseURL+"/api/ticket/get", "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result TicketResponse
json.Unmarshal(body, &result)
return &result, nil
}
type TicketProcessRequest struct {
TicketData string `json:"ticket_data"`
}
type TicketProcessResponse struct {
RetCode string `json:"retCode"`
Message string `json:"message"`
TicketToken string `json:"ticket_token"`
Username string `json:"username"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
func ProcessTicket(ticketData string) (*TicketProcessResponse, error) {
reqBody, _ := json.Marshal(TicketProcessRequest{TicketData: ticketData})
resp, err := http.Post(baseURL+"/api/ticket/process", "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result TicketProcessResponse
json.Unmarshal(body, &result)
return &result, nil
}
type UserInfo struct {
AccountID string `json:"accountID"`
Name string `json:"name"`
UserCode string `json:"userCode"`
ContactNumber string `json:"contactNumber"`
}
type TokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
func CreateTokens(user UserInfo) (*TokenResponse, error) {
reqBody, _ := json.Marshal(user)
resp, err := http.Post(baseURL+"/auth/tokens", "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result TokenResponse
json.Unmarshal(body, &result)
return &result, nil
}
type VerifyRequest struct {
Token string `json:"token"`
}
type VerifyResponse struct {
Valid bool `json:"valid"`
TokenType string `json:"token_type"`
AccountID string `json:"accountID"`
Name string `json:"name"`
UserCode string `json:"userCode"`
ContactNumber string `json:"contactNumber"`
Exp int64 `json:"exp"`
}
func VerifyToken(token string) (*VerifyResponse, error) {
reqBody, _ := json.Marshal(VerifyRequest{Token: token})
resp, err := http.Post(baseURL+"/auth/verify", "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result VerifyResponse
json.Unmarshal(body, &result)
return &result, nil
}
type AccountQueryRequest struct {
CurPage int `json:"cur_page"`
PageSize int `json:"page_size"`
UserCode string `json:"user_code,omitempty"`
UserName string `json:"user_name,omitempty"`
OrgCode string `json:"org_code,omitempty"`
}
func QueryAccounts(req AccountQueryRequest) (map[string]interface{}, error) {
reqBody, _ := json.Marshal(req)
resp, err := http.Post(baseURL+"/api/account/query", "application/json", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
return result, nil
}
func main() {
// 1. 获取票据
ticket, _ := GetTicket()
fmt.Printf("票据: %s\n", ticket.SSOTicket[:50])
// 2. 处理票据获取JWT
jwt, _ := ProcessTicket(ticket.SSOTicket)
fmt.Printf("用户: %s, Token: %s\n", jwt.Username, jwt.RefreshToken[:50])
// 3. 验证Token
verify, _ := VerifyToken(jwt.RefreshToken)
fmt.Printf("验证结果: %v, 用户: %s\n", verify.Valid, verify.Name)
// 4. 查询账号
accounts, _ := QueryAccounts(AccountQueryRequest{CurPage: 1, PageSize: 10})
fmt.Printf("账号总数: %v\n", accounts["recordsTotal"])
}