auth_client.go 9.3 KB

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