hikvision/iot/hikvision-iot.go

130 lines
2.6 KiB
Go

package cloud
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"time"
)
var (
baseURL = "https://api2.hik-cloud.com/oauth"
clientID = ""
clientSecret = ""
scope = ""
)
func init() {
baseURL = os.Getenv("HIK_IOT_URL")
if baseURL == "" {
baseURL = "https://api2.hik-cloud.com/oauth"
}
}
// 基础云眸http请求
func hikvisionRequest(method string, url string, body interface{}) ([]byte, error) {
b, err := json.Marshal(body)
if err != nil {
return nil, err
}
reqbody := strings.NewReader(string(b))
req, err := http.NewRequest(method, url, reqbody)
if err != nil {
return nil, err
}
token, err := hikvisionOauth()
if err != nil {
return nil, err
}
req.Header.Add("authorization", fmt.Sprintf(" bearer %s", token))
if strings.ToLower(method) == "post" {
req.Header.Add("Content-Type", "application/json")
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return respBody, nil
}
var token string
var expired time.Time
type OauthResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
}
// 客户端认证获取access_token
func hikvisionOauth() (*string, error) {
if expired.Before(time.Now()) {
return &token, nil
}
params := url.Values{}
params.Add("client_id", clientID)
params.Add("client_secret", clientSecret)
params.Add("grant_type", "client_credentials")
params.Add("scope", scope)
req, err := http.NewRequest("POST", fmt.Sprintf(`%s/token`, baseURL), strings.NewReader(string(params.Encode())))
if err != nil {
return nil, err
}
req.Header.Add("Accept", "*/*")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
client := &http.Client{Transport: tr, Timeout: 10 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
errmsg := fmt.Sprintf("http status code: %d", resp.StatusCode)
return nil, errors.New(errmsg)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var result *OauthResponse
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, err
}
token = result.AccessToken
expired = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
return &token, nil
}