代码拉取完成,页面将自动刷新
package utils
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"errors"
"fmt"
"io/ioutil"
"os"
"strconv"
"time"
"github.com/spf13/cast"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
)
var ssUrl = "http://127.0.0.1:9500"
func GetAppToken(cfg *viper.Viper, tokenKey, appName string, sansanUrl ...string) (token string, err error) {
if cfg == nil || len(tokenKey) == 0 {
return
}
token = cfg.GetString(tokenKey)
if len(token) > 0 {
// 存在则直接返回
return
}
if len(sansanUrl) > 0 && len(sansanUrl[0]) > 0 {
// 支持指定ssurl
ssUrl = sansanUrl[0]
}
// 先登录拿到接口token
var tmp string
if tmp, err = loginByInitAdmin(); err != nil {
return
}
if len(tmp) == 0 {
err = errors.New("登录三三失败")
return
}
// 添加应用并得到永久token
if token, err = addAppToken(tmp, appName); err != nil {
return
}
// 保存token到配置文件
cfg.Set(tokenKey, token)
data, _ := yaml.Marshal(cfg.AllSettings())
if err = ioutil.WriteFile(cfg.ConfigFileUsed(), data, os.ModePerm); err != nil {
err = errors.New(fmt.Sprintf("write settings file error. %s", err.Error()))
}
return
}
func loginByInitAdmin() (tmp string, err error) {
tsn := time.Now().UnixMilli()
tss := strconv.FormatInt(tsn, 10)
password, err := encodedPassword("123456aa", tsn)
var resp map[string]interface{}
if resp, err = sansanLogin("admin", password, tss); err != nil {
return
}
if b, ok := resp["result"]; ok {
if bMap, ok := b.(map[string]interface{}); ok {
if c, ok := bMap["token"]; ok {
tmp = cast.ToString(c)
}
}
}
return
}
func addAppToken(tk, appName string) (token string, err error) {
param := make(map[string]interface{})
param["appName"] = appName
param["expireTime"] = time.Now().Add(99 * 365 * 24 * time.Hour).Format("2006-01-02 15:04:05")
param["status"] = "1"
param["mode"] = "all"
header := make(map[string]string)
header["Authentication"] = tk
var resultJson interface{}
err = HttpPostJson(ssUrl+"/api/user/app/add", param, header, &resultJson)
if err != nil {
err = errors.New("app接口异常" + err.Error())
return
}
if resultJson == nil {
err = errors.New("app接口异常,响应nil")
return
}
resp := resultJson.(map[string]interface{})
if resp["code"] == nil || resp["code"].(float64) != 200 {
errMsg := If(resp["message"] != nil, resp["message"], "app token失败").(string)
err = errors.New(errMsg)
return
}
token = cast.ToString(cast.ToStringMap(resp["result"])["appToken"])
return
}
func encodedPassword(password string, timestamp int64) (string, error) {
// 生成密钥和IV
key := fmt.Sprintf("aes%d", timestamp)
// 创建AES加密块
block, err := aes.NewCipher([]byte(key))
if err != nil {
err = errors.New("AES加密失败" + err.Error())
return "", err
}
// 使用PKCS5Padding填充
paddedPassword := pkcs5Padding([]byte(password), block.BlockSize())
// 设置IV(与key相同)
iv := []byte(key)
// 创建CBC加密模式
mode := cipher.NewCBCEncrypter(block, iv)
// 加密
ciphertext := make([]byte, len(paddedPassword))
mode.CryptBlocks(ciphertext, paddedPassword)
// Base64编码
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// PKCS5Padding 实现
func pkcs5Padding(src []byte, blockSize int) []byte {
padding := blockSize - len(src)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}
func sansanLogin(username, password string, authtimestamp string) (resp map[string]interface{}, err error) {
// 执行
param := make(map[string]interface{})
param["username"] = username
param["password"] = password
header := make(map[string]string)
header["authtimestamp"] = authtimestamp
var resultJson interface{}
err = HttpPostJson(ssUrl+"/api/auth/login", param, header, &resultJson)
if err != nil {
err = errors.New("登录接口异常" + err.Error())
return
}
if resultJson == nil {
err = errors.New("登录接口异常,响应nil")
return
}
resp = resultJson.(map[string]interface{})
if resp["code"] == nil || resp["code"].(float64) != 200 {
errMsg := If(resp["message"] != nil, resp["message"], "登录失败").(string)
err = errors.New(errMsg)
return
}
return
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。