Files
xiaomihome/xiaomi/examples/15_oauth_flow/main.go
T
4566704 cdc459b5ff fix(xiaomihome): 模块路径改为 git.zeroonesoft.cn/golib/xiaomihome
- 改动:go.mod module 声明与全部内部导入路径补全为完整域名路径,README 同步
- 原因:裸模块名无法被 go get 解析,发版前必须修正为 GOPRIVATE 可拉取路径
2026-10-05 08:53:23 +08:00

98 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 示例 15:OAuth 授权流程(无需 import miot)
//
// go run . 首次运行自动创建 user.json,打开授权链接完成授权后粘贴 code。
package main
import (
"bufio"
"crypto/rand"
"context"
"encoding/json"
"fmt"
"log"
"os"
"git.zeroonesoft.cn/golib/xiaomihome/xiaomi"
)
type userFile struct {
UID string `json:"uid"`
UUID string `json:"uuid"`
Auth struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresTS int64 `json:"expires_ts"`
} `json:"auth"`
DataDir string `json:"data_dir"`
}
const filePath = "user.json"
func load() *userFile {
data, _ := os.ReadFile(filePath)
var u userFile
json.Unmarshal(data, &u)
if u.UUID == "" {
u.UUID = newUUID()
save(&u)
}
return &u
}
func save(u *userFile) {
data, _ := json.MarshalIndent(u, "", " ")
os.WriteFile(filePath, data, 0600)
}
func newUUID() string {
b := make([]byte, 16)
rand.Read(b)
return fmt.Sprintf("%x", b)
}
func main() {
ctx := context.Background()
u := load()
if u.Auth.AccessToken != "" {
fmt.Println("已完成授权")
fmt.Printf("UID: %s\n", u.UID)
fmt.Printf("AccessToken: %s...\n", u.Auth.AccessToken[:min(20, len(u.Auth.AccessToken))])
fmt.Printf("RefreshToken: %s...\n", u.Auth.RefreshToken[:min(20, len(u.Auth.RefreshToken))])
return
}
authURL := xiaomi.AuthURL(xiaomi.Config{UUID: u.UUID})
fmt.Println("========== OAuth 授权 ==========")
fmt.Println("请打开以下链接完成授权,然后把地址栏中的 code 粘贴回来:")
fmt.Println()
fmt.Println(" ", authURL)
fmt.Println()
fmt.Print("输入 code: ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
code := scanner.Text()
if code == "" {
log.Fatal("未输入 code")
}
result, err := xiaomi.ExchangeCode(ctx, xiaomi.Config{UUID: u.UUID}, code)
if err != nil {
log.Fatal("ExchangeCode 失败:", err)
}
u.UID = result.UID
u.Auth.AccessToken = result.AccessToken
u.Auth.RefreshToken = result.RefreshToken
u.Auth.ExpiresTS = result.ExpiresTS
u.DataDir = "./data/" + u.UID
save(u)
fmt.Println("\n=== Token 已保存 ===")
fmt.Printf("UID: %s\n", u.UID)
fmt.Printf("AccessToken: %s...\n", u.Auth.AccessToken[:min(20, len(u.Auth.AccessToken))])
fmt.Printf("RefreshToken: %s...\n", u.Auth.RefreshToken[:min(20, len(u.Auth.RefreshToken))])
}