token.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. // ERP 代码, light的逻辑, 废弃!!!!!
  2. // ERP 代码, light的逻辑, 废弃!!!!!
  3. package utils
  4. import (
  5. "bytes"
  6. "crypto/md5"
  7. "encoding/binary"
  8. "encoding/hex"
  9. "encoding/json"
  10. "errors"
  11. "fmt"
  12. "io/ioutil"
  13. "log"
  14. "net"
  15. "net/http"
  16. "strconv"
  17. "strings"
  18. "sync"
  19. "time"
  20. "git.i2edu.net/i2/go-zero/core/logx"
  21. "git.i2edu.net/i2/i2-bill-erp/internal/config"
  22. )
  23. type Token struct {
  24. Lock *sync.RWMutex
  25. Result int `json:"-"`
  26. UserId string `json:"user_id"`
  27. AccessToken string `json:"access_token"`
  28. RefreshToken string `json:"refresh_token"`
  29. LoginID string `json:"login_id"`
  30. TimeStamp uint64 `json:"time_stamp"`
  31. ServerIp string `json:"server_ip"`
  32. Domain string `json:"domain"`
  33. Password string `json:"-"`
  34. Map map[string]interface{} `json:"map"`
  35. }
  36. type TokenStore struct {
  37. storeServiceUrl string
  38. name string
  39. lock *sync.RWMutex
  40. tokens map[string]*Token
  41. }
  42. type IAuth interface {
  43. Init()
  44. }
  45. var globalTokenStore *TokenStore = nil
  46. func Init(c *config.Config) {
  47. globalTokenStore = &TokenStore{name: "sso", lock: new(sync.RWMutex), tokens: make(map[string]*Token)}
  48. if strings.HasPrefix(c.Erp.AuthServer, "http") {
  49. globalTokenStore.storeServiceUrl = c.Erp.AuthServer
  50. } else {
  51. iauthMap = make(map[string]IAuth)
  52. go globalTokenStore.startTokenCheckProcess()
  53. lightAuth := &LightAuth{}
  54. RegisterAuth("qianqiusoft.com", lightAuth)
  55. erpClient := NewTcpClient(c)
  56. erpClient.Start()
  57. }
  58. }
  59. type LightAuth struct {
  60. }
  61. func (la *LightAuth) Init() {
  62. }
  63. var iauthMap map[string]IAuth
  64. /**
  65. * @brief: 注册自定登录对象, 会调用Init进行初始化
  66. * @param1 t: key
  67. * @param2 a: 认证对象
  68. * @return none
  69. */
  70. func RegisterAuth(t string, a IAuth) {
  71. if t == "" || a == nil {
  72. return
  73. }
  74. var ok bool
  75. if _, ok = iauthMap[t]; ok {
  76. return
  77. } else {
  78. a.Init()
  79. iauthMap[t] = a
  80. }
  81. }
  82. func GetGlobalTokenStore() *TokenStore {
  83. return globalTokenStore
  84. }
  85. func (t *TokenStore) Get(key string) string {
  86. if t.storeServiceUrl == "" {
  87. t.lock.RLock()
  88. defer t.lock.RUnlock()
  89. if val, ok := t.tokens[key]; ok {
  90. //log.Println(key, "获取Token:", val.AccessToken, val.RefreshToken, val.LoginID)
  91. return val.UserId
  92. }
  93. } else {
  94. resp, err := http.Get(t.storeServiceUrl + key)
  95. if err != nil {
  96. return ""
  97. }
  98. b, err := ioutil.ReadAll(resp.Body)
  99. if err != nil {
  100. return ""
  101. }
  102. token := &Token{}
  103. err = json.Unmarshal(b, &token)
  104. if err != nil {
  105. return ""
  106. }
  107. return token.UserId
  108. }
  109. return ""
  110. }
  111. func (t *TokenStore) Set(key string, v *Token) {
  112. t.lock.Lock()
  113. defer t.lock.Unlock()
  114. if val, ok := t.tokens[key]; !ok {
  115. t.tokens[key] = v
  116. } else if val != v {
  117. t.tokens[key] = v
  118. }
  119. }
  120. func (t *TokenStore) Remove(key string) {
  121. t.lock.Lock()
  122. defer t.lock.Unlock()
  123. delete(t.tokens, key)
  124. log.Println(key, "删除Key")
  125. }
  126. func (t *TokenStore) Refresh(key string) {
  127. t.lock.Lock()
  128. defer t.lock.Unlock()
  129. val, ok := t.tokens[key]
  130. if ok {
  131. val.TimeStamp = uint64(time.Now().UnixNano())
  132. }
  133. }
  134. func (t *TokenStore) startTokenCheckProcess() {
  135. }
  136. const (
  137. __KEY = "Light#dauth-@*I2"
  138. CMD_NEW = "new"
  139. CMD_REMOVE = "remove"
  140. CMD_PINGPONG = "pg"
  141. CMD_PINGPONG_RESP = "pg_resp"
  142. )
  143. var TCPClient *TcpClient
  144. type authPackage struct {
  145. Cmd string
  146. TokenStr string
  147. Content []byte
  148. }
  149. func (ap *authPackage) toBytes() []byte {
  150. buf := bytes.NewBuffer([]byte{})
  151. b := []byte(ap.Cmd)
  152. buf.Write(uint32ToBytes(len(b)))
  153. buf.Write(b)
  154. buf.Write(uint32ToBytes(len(ap.Content)))
  155. buf.Write(ap.Content)
  156. return buf.Bytes()
  157. }
  158. type TcpClient struct {
  159. conn net.Conn // 连接
  160. c *config.Config
  161. pchan chan *authPackage // 包chan
  162. done chan bool // 是否done
  163. exited bool // 退出
  164. verified bool // 验证是否
  165. }
  166. // 创建client
  167. func NewTcpClient(cfg *config.Config) *TcpClient {
  168. c := &TcpClient{
  169. c: cfg,
  170. pchan: make(chan *authPackage, 100),
  171. done: make(chan bool),
  172. exited: false,
  173. verified: false,
  174. }
  175. return c
  176. }
  177. // 启动
  178. func (c *TcpClient) Start() {
  179. go func() {
  180. defer func() {
  181. if p := recover(); p != nil {
  182. fmt.Println("ecover", p)
  183. }
  184. if c.conn != nil {
  185. c.conn.Close()
  186. }
  187. c.restart()
  188. }()
  189. var err error = nil
  190. address := c.c.Erp.AuthServer
  191. // fmt.Println("auth client start, dial address is", address)
  192. c.conn, err = net.Dial("tcp", address)
  193. if err != nil {
  194. fmt.Println("Error dialing erp client", err.Error())
  195. return
  196. }
  197. fmt.Println("发送验证")
  198. sendVerify(c.conn) // 发送验证,不需要读取返回值,如果验证错误立刻关掉
  199. fmt.Println("读取验证结果")
  200. vresp, err := readString(c.conn)
  201. if err != nil {
  202. fmt.Println("Error dialing", err.Error())
  203. return
  204. }
  205. if vresp != "ok" {
  206. // 验证失败
  207. fmt.Println("verify is not ok", vresp)
  208. return
  209. }
  210. fmt.Println("验证成功")
  211. c.verified = true
  212. // send
  213. go func() {
  214. for {
  215. select {
  216. case data := <-c.pchan:
  217. logx.Info("写入数据")
  218. c.conn.SetWriteDeadline(time.Now().Add(time.Second * 2))
  219. _, err := c.conn.Write(data.toBytes())
  220. if err != nil {
  221. fmt.Println("写入内容错误", err.Error())
  222. return
  223. }
  224. case <-c.done:
  225. logx.Info("发送数据done退出")
  226. return
  227. }
  228. }
  229. }()
  230. // receive
  231. for {
  232. cmd, err := readString(c.conn) // 读取命令
  233. if err != nil {
  234. c.done <- true
  235. fmt.Println("读取命令错误", err.Error())
  236. break
  237. }
  238. if cmd == CMD_NEW {
  239. err = c.newHandler()
  240. } else if cmd == CMD_REMOVE {
  241. err = c.removeHandler()
  242. } else if cmd == CMD_PINGPONG_RESP {
  243. } else {
  244. fmt.Println("未知cmd", cmd)
  245. continue
  246. }
  247. if err != nil {
  248. c.done <- true
  249. fmt.Println("处理错误", err.Error())
  250. break
  251. }
  252. }
  253. }()
  254. }
  255. // 停止
  256. func (c *TcpClient) Stop() {
  257. c.exited = true
  258. c.conn.Close()
  259. }
  260. // 检测
  261. func (c *TcpClient) restart() {
  262. if c.exited {
  263. // 已退出则不重启
  264. return
  265. }
  266. go func() {
  267. c.verified = false
  268. c.done = make(chan bool)
  269. c.pchan = make(chan *authPackage, 100)
  270. c.exited = false
  271. time.Sleep(3 * time.Second)
  272. c.Start()
  273. }()
  274. }
  275. // 发送bytes
  276. func (c *TcpClient) Send(cmd string, bytess []byte) {
  277. if !c.verified {
  278. fmt.Println("未认证")
  279. return
  280. }
  281. logx.Info("发送指令1", cmd)
  282. c.pchan <- &authPackage{
  283. Cmd: cmd,
  284. Content: bytess,
  285. }
  286. logx.Info("发送指令2", cmd)
  287. }
  288. // 发送token
  289. func (c *TcpClient) SendToken(token *Token) {
  290. // logx.Info("发送新建token")
  291. bytess := tokenToBytes(token)
  292. c.Send(CMD_NEW, bytess)
  293. }
  294. // 处理创建
  295. func (c *TcpClient) newHandler() error {
  296. // fmt.Println("处理新建")
  297. bytess, err := readBytes(c.conn)
  298. if err != nil {
  299. fmt.Println("读取token内容错误", err.Error())
  300. return err
  301. }
  302. // 新建
  303. token, err := bytesToToken(bytess)
  304. if err != nil {
  305. logx.Info("bytesToToken 错误", err.Error())
  306. return err
  307. }
  308. GetGlobalTokenStore().Set(token.AccessToken, token)
  309. return nil
  310. }
  311. // 处理删除
  312. func (c *TcpClient) removeHandler() error {
  313. fmt.Println("处理删除")
  314. bytess, err := readBytes(c.conn)
  315. if err != nil {
  316. fmt.Println("读取token内容错误", err.Error())
  317. return err
  318. }
  319. // 移除,此时bytess为tokenstring
  320. GetGlobalTokenStore().Remove(string(bytess))
  321. return nil
  322. }
  323. // 读取字符串
  324. func readString(conn net.Conn) (string, error) {
  325. // 读长度
  326. size, err := readUInt32(conn)
  327. if err != nil {
  328. fmt.Println("读取长度失败,", err.Error())
  329. return "", err
  330. }
  331. // 读字符串
  332. b := make([]byte, size)
  333. n, err := conn.Read(b)
  334. if n != int(size) {
  335. return "", errors.New("读取长度不是" + strconv.Itoa(int(size)))
  336. }
  337. return string(b), nil
  338. }
  339. // 写入字符串
  340. func writeString(conn net.Conn, str string) error {
  341. if str == "" {
  342. return errors.New("字符串为空")
  343. }
  344. bytess := []byte(str)
  345. size := len(bytess)
  346. // 发送长度
  347. err := writeUInt32(conn, uint32(size))
  348. if err != nil {
  349. fmt.Println("发送长度失败,", err.Error())
  350. return err
  351. }
  352. // 发送内容
  353. n, err := conn.Write(bytess)
  354. if err != nil {
  355. fmt.Println("发送内容失败,", err.Error())
  356. return err
  357. }
  358. if n != size {
  359. return errors.New("发送长度不是" + strconv.Itoa(int(size)))
  360. }
  361. return nil
  362. }
  363. // 读取bytes
  364. func readBytes(conn net.Conn) ([]byte, error) {
  365. // 读长度
  366. size, err := readUInt32(conn)
  367. if err != nil {
  368. fmt.Println("读取长度失败,", err.Error())
  369. return nil, err
  370. }
  371. // 读字符串
  372. b := make([]byte, size)
  373. n, err := conn.Read(b)
  374. if n != int(size) {
  375. return nil, errors.New("读取长度不是" + strconv.Itoa(int(size)))
  376. }
  377. return b, nil
  378. }
  379. // 读取uint64
  380. func readUInt32(conn net.Conn) (uint32, error) {
  381. b := make([]byte, 4)
  382. n, err := conn.Read(b)
  383. if err != nil {
  384. fmt.Println("读取长度失败,", err.Error())
  385. return 0, err
  386. }
  387. if n != 4 {
  388. return 0, errors.New("读取长度不是4")
  389. }
  390. size := binary.BigEndian.Uint32(b)
  391. return size, nil
  392. }
  393. // 写入长度
  394. func writeUInt32(conn net.Conn, v uint32) error {
  395. // 发送长度
  396. b := make([]byte, 4)
  397. binary.BigEndian.PutUint32(b, v)
  398. n, err := conn.Write(b)
  399. if err != nil {
  400. fmt.Println("发送长度失败,", err.Error())
  401. return err
  402. }
  403. if n != 4 {
  404. return errors.New("发送长度不是4")
  405. }
  406. return nil
  407. }
  408. // 写入长度
  409. func writeUInt64(conn net.Conn, v uint64) error {
  410. // 发送长度
  411. b := make([]byte, 8)
  412. binary.BigEndian.PutUint64(b, v)
  413. n, err := conn.Write(b)
  414. if err != nil {
  415. fmt.Println("发送长度失败,", err.Error())
  416. return err
  417. }
  418. if n != 4 {
  419. return errors.New("发送长度不是4")
  420. }
  421. return nil
  422. }
  423. // 读取uint64
  424. func readStringByBytes(bytess []byte) (string, int, error) {
  425. size := binary.BigEndian.Uint32(bytess)
  426. return string(bytess[4 : 4+size]), int(size), nil
  427. }
  428. // int转bytes
  429. func uint32ToBytes(v int) []byte {
  430. b := make([]byte, 4)
  431. binary.BigEndian.PutUint32(b, uint32(v))
  432. return b
  433. }
  434. // int转bytes
  435. func uint64ToBytes(v int) []byte {
  436. b := make([]byte, 8)
  437. binary.BigEndian.PutUint32(b, uint32(v))
  438. return b
  439. }
  440. // 转token
  441. func bytesToToken(content []byte) (*Token, error) {
  442. token := &Token{Lock: new(sync.RWMutex)}
  443. var index int = 0
  444. var size int
  445. var err error = nil
  446. // fmt.Println("读取userid")
  447. token.UserId, size, err = readStringByBytes(content)
  448. if err != nil {
  449. fmt.Println("读取userid错误")
  450. return nil, err
  451. }
  452. index += 4 + size
  453. // fmt.Println("读取AccessToken")
  454. token.AccessToken, size, err = readStringByBytes(content[index:])
  455. if err != nil {
  456. fmt.Println("读取AccessToken错误")
  457. return nil, err
  458. }
  459. index += 4 + size
  460. // fmt.Println("读取RefreshToken")
  461. token.RefreshToken, size, err = readStringByBytes(content[index:])
  462. if err != nil {
  463. fmt.Println("读取RefreshToken错误")
  464. return nil, err
  465. }
  466. index += 4 + size
  467. // fmt.Println("读取LoginID")
  468. token.LoginID, size, err = readStringByBytes(content[index:])
  469. if err != nil {
  470. fmt.Println("读取LoginID错误")
  471. return nil, err
  472. }
  473. index += 4 + size
  474. // fmt.Println("读取timestamp")
  475. token.TimeStamp = binary.BigEndian.Uint64(content[index:])
  476. index += 8
  477. // fmt.Println("读取ServerIp")
  478. token.ServerIp, size, err = readStringByBytes(content[index:])
  479. if err != nil {
  480. fmt.Println("读取ServerIp错误")
  481. return nil, err
  482. }
  483. index += 4 + size
  484. // fmt.Println("读取Domain")
  485. token.Domain, size, err = readStringByBytes(content[index:])
  486. if err != nil {
  487. fmt.Println("读取Domain错误")
  488. return nil, err
  489. }
  490. index += 4 + size
  491. return token, nil
  492. }
  493. // 转bytes,包括token开头
  494. func tokenToBytes(token *Token) []byte {
  495. buf := bytes.NewBuffer([]byte{})
  496. t := []byte(token.UserId)
  497. buf.Write(uint32ToBytes(len(t)))
  498. buf.Write(t)
  499. t = []byte(token.AccessToken)
  500. buf.Write(uint32ToBytes(len(t)))
  501. buf.Write(t)
  502. t = []byte(token.RefreshToken)
  503. buf.Write(uint32ToBytes(len(t)))
  504. buf.Write(t)
  505. t = []byte(token.LoginID)
  506. buf.Write(uint32ToBytes(len(t)))
  507. buf.Write(t)
  508. buf.Write(uint64ToBytes(int(token.TimeStamp)))
  509. fmt.Println(token.ServerIp)
  510. t = []byte(token.ServerIp)
  511. buf.Write(uint32ToBytes(len(t)))
  512. buf.Write(t)
  513. fmt.Println(token.Domain)
  514. t = []byte(token.Domain)
  515. buf.Write(uint32ToBytes(len(t)))
  516. buf.Write(t)
  517. bytess := buf.Bytes()
  518. buf = bytes.NewBuffer([]byte{}) // 这里用reset是错误的
  519. tokenstrbytes := []byte(token.AccessToken)
  520. buf.Write(uint32ToBytes(len(tokenstrbytes)))
  521. buf.Write(tokenstrbytes)
  522. buf.Write(uint32ToBytes(len(bytess)))
  523. buf.Write(bytess)
  524. return buf.Bytes()
  525. }
  526. // 发送验证
  527. func sendVerify(conn net.Conn) {
  528. timestamp := time.Now().UnixNano()
  529. timestampStr := strconv.Itoa(int(timestamp))
  530. seed := timestampStr + __KEY
  531. hashVal := hash(seed)
  532. writeUInt64(conn, uint64(timestamp))
  533. writeString(conn, hashVal)
  534. }
  535. // md5 哈希
  536. func hash(str string) string {
  537. h := md5.New()
  538. h.Write([]byte(str))
  539. return hex.EncodeToString(h.Sum(nil))
  540. }