auth_client.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. package auth
  2. import (
  3. "bytes"
  4. "crypto/md5"
  5. "encoding/binary"
  6. "encoding/hex"
  7. "errors"
  8. "fmt"
  9. "git.qianqiusoft.com/public/glog"
  10. "git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
  11. "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
  12. sysutils "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
  13. "net"
  14. "strconv"
  15. "time"
  16. )
  17. const (
  18. __KEY = "Light#dauth-@*I2"
  19. CMD_NEW = "new"
  20. CMD_REMOVE = "remove"
  21. CMD_PINGPONG = "pg"
  22. CMD_PINGPONG_RESP = "pg_resp"
  23. )
  24. var TCPClient *TcpClient
  25. type authPackage struct {
  26. Cmd string
  27. TokenStr string
  28. Content []byte
  29. }
  30. func (ap *authPackage)toBytes()[]byte{
  31. buf := bytes.NewBuffer([]byte{})
  32. b := []byte(ap.Cmd)
  33. buf.Write(uint32ToBytes(len(b)))
  34. buf.Write(b)
  35. buf.Write(uint32ToBytes(len(ap.Content)))
  36. buf.Write(ap.Content)
  37. bytess := buf.Bytes()
  38. fmt.Println(bytess)
  39. return bytess
  40. }
  41. type TcpClient struct {
  42. conn net.Conn
  43. pchan chan *authPackage
  44. done chan bool
  45. exited bool
  46. verified bool
  47. }
  48. // 创建client
  49. func NewTcpClient()*TcpClient{
  50. c := &TcpClient{
  51. pchan: make(chan *authPackage, 100),
  52. done: make(chan bool),
  53. exited: false,
  54. verified: false,
  55. }
  56. return c
  57. }
  58. // 启动
  59. func(c *TcpClient)Start() {
  60. go func() {
  61. defer func() {
  62. if p := recover(); p != nil {
  63. fmt.Println("ecover", p)
  64. }
  65. c.restart()
  66. }()
  67. var err error = nil
  68. address := config.AppConfig.GetKey("auth_server")
  69. fmt.Println("auth client start, dial address is", address)
  70. c.conn, err = net.Dial("tcp", address)
  71. if err != nil {
  72. fmt.Println("Error dialing", err.Error())
  73. return
  74. }
  75. fmt.Println("发送验证")
  76. sendVerify(c.conn) // 发送验证,不需要读取返回值,如果验证错误立刻关掉
  77. fmt.Println("读取验证结果")
  78. vresp, err := readString(c.conn)
  79. if err != nil {
  80. fmt.Println("Error dialing", err.Error())
  81. return
  82. }
  83. if vresp != "ok"{
  84. // 验证失败
  85. fmt.Println("verify is not ok", vresp)
  86. return
  87. }
  88. fmt.Println("验证成功")
  89. c.verified = true
  90. // send
  91. go func() {
  92. for {
  93. select {
  94. case data := <-c.pchan:
  95. _, err := c.conn.Write(data.toBytes())
  96. if err != nil {
  97. fmt.Println("写入内容错误", err.Error())
  98. return
  99. }
  100. case <-c.done:
  101. return
  102. }
  103. }
  104. }()
  105. // receive
  106. for {
  107. cmd, err := readString(c.conn) // 读取命令
  108. if err != nil {
  109. c.done <- true
  110. fmt.Println("读取命令错误", err.Error())
  111. break
  112. }
  113. if cmd == CMD_NEW{
  114. err = c.newHandler()
  115. } else if cmd == CMD_REMOVE{
  116. err = c.removeHandler()
  117. } else if cmd == CMD_PINGPONG_RESP{
  118. } else {
  119. fmt.Println("未知cmd", cmd)
  120. continue
  121. }
  122. if err != nil{
  123. c.done <- true
  124. fmt.Println("处理错误", err.Error())
  125. break
  126. }
  127. }
  128. }()
  129. }
  130. // 停止
  131. func(c *TcpClient)Stop(){
  132. c.exited = true
  133. c.conn.Close()
  134. }
  135. // 检测
  136. func(c *TcpClient)restart(){
  137. if c.exited{
  138. // 已退出则不重启
  139. return
  140. }
  141. go func(){
  142. time.Sleep(3 * time.Second)
  143. c.verified = false
  144. c.Start()
  145. }()
  146. }
  147. // 发送bytes
  148. func(c *TcpClient)Send(cmd string, bytess []byte){
  149. if !c.verified{
  150. fmt.Println("未认证")
  151. return
  152. }
  153. c.pchan <- &authPackage{
  154. Cmd: cmd,
  155. Content: bytess,
  156. }
  157. }
  158. // 发送token
  159. func(c *TcpClient)SendToken(token *entitys.Token){
  160. glog.Infoln("发送新建token")
  161. bytess := tokenToBytes(token)
  162. fmt.Println(bytess)
  163. c.Send(CMD_NEW, bytess)
  164. }
  165. // 处理创建
  166. func(c *TcpClient)newHandler()error{
  167. fmt.Println("处理新建")
  168. bytess, err := readBytes(c.conn)
  169. if err != nil {
  170. fmt.Println("读取token内容错误", err.Error())
  171. return err
  172. }
  173. fmt.Println(len(bytess))
  174. fmt.Println(bytess)
  175. // 新建
  176. token, err := bytesToToken(bytess)
  177. if err != nil{
  178. glog.Infoln("bytesToToken 错误", err.Error())
  179. return err
  180. }
  181. sysutils.GetGlobalTokenStore().Set(token.AccessToken, token)
  182. return nil
  183. }
  184. // 处理删除
  185. func(c *TcpClient)removeHandler()error{
  186. fmt.Println("处理删除")
  187. bytess, err := readBytes(c.conn)
  188. if err != nil {
  189. fmt.Println("读取token内容错误", err.Error())
  190. return err
  191. }
  192. // 移除,此时bytess为tokenstring
  193. sysutils.GetGlobalTokenStore().Remove(string(bytess))
  194. return nil
  195. }
  196. // 读取字符串
  197. func readString(conn net.Conn)(string, error){
  198. // 读长度
  199. size, err := readUInt32(conn)
  200. if err != nil{
  201. fmt.Println("读取长度失败,", err.Error())
  202. return "", err
  203. }
  204. // 读字符串
  205. b := make([]byte, size)
  206. n, err := conn.Read(b)
  207. if n != int(size){
  208. return "", errors.New("读取长度不是" + strconv.Itoa(int(size)))
  209. }
  210. return string(b), nil
  211. }
  212. // 写入字符串
  213. func writeString(conn net.Conn, str string)error{
  214. if str == ""{
  215. return errors.New("字符串为空")
  216. }
  217. bytess := []byte(str)
  218. size := len(bytess)
  219. // 发送长度
  220. err := writeUInt32(conn, uint32(size))
  221. if err != nil{
  222. fmt.Println("发送长度失败,", err.Error())
  223. return err
  224. }
  225. // 发送内容
  226. n, err := conn.Write(bytess)
  227. if err != nil{
  228. fmt.Println("发送内容失败,", err.Error())
  229. return err
  230. }
  231. if n != size{
  232. return errors.New("发送长度不是" + strconv.Itoa(int(size)))
  233. }
  234. return nil
  235. }
  236. // 读取bytes
  237. func readBytes(conn net.Conn)([]byte, error){
  238. // 读长度
  239. size, err := readUInt32(conn)
  240. if err != nil{
  241. fmt.Println("读取长度失败,", err.Error())
  242. return nil, err
  243. }
  244. // 读字符串
  245. b := make([]byte, size)
  246. n, err := conn.Read(b)
  247. if n != int(size){
  248. return nil, errors.New("读取长度不是" + strconv.Itoa(int(size)))
  249. }
  250. return b, nil
  251. }
  252. // 读取uint64
  253. func readUInt32(conn net.Conn)(uint32, error){
  254. b := make([]byte, 4)
  255. n, err := conn.Read(b)
  256. if err != nil{
  257. fmt.Println("读取长度失败,", err.Error())
  258. return 0, err
  259. }
  260. if n != 4{
  261. return 0, errors.New("读取长度不是4")
  262. }
  263. size := binary.BigEndian.Uint32(b)
  264. return size, nil
  265. }
  266. // 写入长度
  267. func writeUInt32(conn net.Conn, v uint32)error{
  268. // 发送长度
  269. b := make([]byte, 4)
  270. binary.BigEndian.PutUint32(b, v)
  271. n, err := conn.Write(b)
  272. if err != nil{
  273. fmt.Println("发送长度失败,", err.Error())
  274. return err
  275. }
  276. if n != 4{
  277. return errors.New("发送长度不是4")
  278. }
  279. return nil
  280. }
  281. // 写入长度
  282. func writeUInt64(conn net.Conn, v uint64)error{
  283. // 发送长度
  284. b := make([]byte, 8)
  285. binary.BigEndian.PutUint64(b, v)
  286. n, err := conn.Write(b)
  287. if err != nil{
  288. fmt.Println("发送长度失败,", err.Error())
  289. return err
  290. }
  291. if n != 4{
  292. return errors.New("发送长度不是4")
  293. }
  294. return nil
  295. }
  296. // 读取uint64
  297. func readStringByBytes(bytess []byte)(string, int, error) {
  298. size := binary.BigEndian.Uint32(bytess)
  299. return string(bytess[4 : 4+size]), int(size), nil
  300. }
  301. // int转bytes
  302. func uint32ToBytes(v int)[]byte{
  303. b := make([]byte, 4)
  304. binary.BigEndian.PutUint32(b, uint32(v))
  305. return b
  306. }
  307. // int转bytes
  308. func uint64ToBytes(v int)[]byte{
  309. b := make([]byte, 8)
  310. binary.BigEndian.PutUint32(b, uint32(v))
  311. return b
  312. }
  313. // 转token
  314. func bytesToToken(content []byte)(*entitys.Token, error){
  315. token := &entitys.Token{}
  316. var index int = 0
  317. var size int
  318. var err error = nil
  319. fmt.Println("读取userid")
  320. token.UserId, size, err = readStringByBytes(content)
  321. if err != nil{
  322. fmt.Println("读取userid错误")
  323. return nil, err
  324. }
  325. index += 4 + size
  326. fmt.Println("读取AccessToken")
  327. token.AccessToken, size, err = readStringByBytes(content[index:])
  328. if err != nil{
  329. fmt.Println("读取AccessToken错误")
  330. return nil, err
  331. }
  332. index += 4 + size
  333. fmt.Println("读取RefreshToken")
  334. token.RefreshToken, size, err = readStringByBytes(content[index:])
  335. if err != nil{
  336. fmt.Println("读取RefreshToken错误")
  337. return nil, err
  338. }
  339. index += 4 + size
  340. fmt.Println("读取LoginID")
  341. token.LoginID, size, err = readStringByBytes(content[index:])
  342. if err != nil{
  343. fmt.Println("读取LoginID错误")
  344. return nil, err
  345. }
  346. index += 4 + size
  347. fmt.Println("读取timestamp")
  348. token.TimeStamp = binary.BigEndian.Uint64(content[index:])
  349. index += 8
  350. fmt.Println("读取ServerIp")
  351. token.ServerIp, size, err = readStringByBytes(content[index:])
  352. if err != nil{
  353. fmt.Println("读取ServerIp错误")
  354. return nil, err
  355. }
  356. index += 4 + size
  357. fmt.Println("读取Domain")
  358. token.Domain, size, err = readStringByBytes(content[index:])
  359. if err != nil{
  360. fmt.Println("读取Domain错误")
  361. return nil, err
  362. }
  363. index += 4 + size
  364. return token, nil
  365. }
  366. // 转bytes,包括token开头
  367. func tokenToBytes(token *entitys.Token)[]byte{
  368. buf := bytes.NewBuffer([]byte{})
  369. t := []byte(token.UserId)
  370. buf.Write(uint32ToBytes(len(t)))
  371. buf.Write(t)
  372. t = []byte(token.AccessToken)
  373. buf.Write(uint32ToBytes(len(t)))
  374. buf.Write(t)
  375. t = []byte(token.RefreshToken)
  376. buf.Write(uint32ToBytes(len(t)))
  377. buf.Write(t)
  378. t = []byte(token.LoginID)
  379. buf.Write(uint32ToBytes(len(t)))
  380. buf.Write(t)
  381. buf.Write(uint64ToBytes(int(token.TimeStamp)))
  382. fmt.Println(token.ServerIp)
  383. t = []byte(token.ServerIp)
  384. buf.Write(uint32ToBytes(len(t)))
  385. buf.Write(t)
  386. fmt.Println(token.Domain)
  387. t = []byte(token.Domain)
  388. buf.Write(uint32ToBytes(len(t)))
  389. buf.Write(t)
  390. bytess := buf.Bytes()
  391. buf = bytes.NewBuffer([]byte{}) // 这里用reset是错误的
  392. tokenstrbytes := []byte(token.AccessToken)
  393. buf.Write(uint32ToBytes(len(tokenstrbytes)))
  394. buf.Write(tokenstrbytes)
  395. buf.Write(uint32ToBytes(len(bytess)))
  396. buf.Write(bytess)
  397. return buf.Bytes()
  398. }
  399. // 发送验证
  400. func sendVerify(conn net.Conn){
  401. timestamp := time.Now().UnixNano()
  402. timestampStr := strconv.Itoa(int(timestamp))
  403. seed := timestampStr + __KEY
  404. hashVal := hash(seed)
  405. writeUInt64(conn, uint64(timestamp))
  406. writeString(conn, hashVal)
  407. }
  408. // md5 哈希
  409. func hash(str string)string{
  410. h := md5.New()
  411. h.Write([]byte(str))
  412. return hex.EncodeToString(h.Sum(nil))
  413. }