token.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package token
  2. import (
  3. "encoding/json"
  4. "f1-game/internal/code"
  5. "fmt"
  6. cherryCrypto "github.com/cherry-game/cherry/extend/crypto"
  7. cherryTime "github.com/cherry-game/cherry/extend/time"
  8. cherryLogger "github.com/cherry-game/cherry/logger"
  9. )
  10. const hashFormat = "pid=%d, oid=%s, tt=%d"
  11. const tokenExpiredDay = 3
  12. type Token struct {
  13. PID int32 `json:"pid"`
  14. OpenID string `json:"open_id"`
  15. Timestamp int64 `json:"tt"`
  16. Hash string `json:"hash"`
  17. }
  18. func New(pid int32, openId string, appKey string) *Token {
  19. token := &Token{
  20. PID: pid,
  21. OpenID: openId,
  22. Timestamp: cherryTime.Now().ToMillisecond(),
  23. }
  24. token.Hash = BuildHash(token, appKey)
  25. return token
  26. }
  27. func (t *Token) ToBase64() string {
  28. bytes, _ := json.Marshal(t)
  29. return cherryCrypto.Base64Encode(string(bytes))
  30. }
  31. func DecodeToken(base64Token string) (*Token, bool) {
  32. if len(base64Token) < 1 {
  33. return nil, false
  34. }
  35. token := &Token{}
  36. bytes, err := cherryCrypto.Base64DecodeBytes(base64Token)
  37. if err != nil {
  38. cherryLogger.Warnf("base64Token = %s, validate error = %v", base64Token, err)
  39. return nil, false
  40. }
  41. err = json.Unmarshal(bytes, token)
  42. if err != nil {
  43. cherryLogger.Warnf("base64Token = %s, unmarshal error = %v", base64Token, err)
  44. return nil, false
  45. }
  46. return token, true
  47. }
  48. func Validate(token *Token, appKey string) (int32, bool) {
  49. now := cherryTime.Now()
  50. now.AddDays(tokenExpiredDay)
  51. if token.Timestamp > now.ToMillisecond() {
  52. cherryLogger.Warnf("token is expired, token = %s", token)
  53. return code.AccountTokenIsExpired, false
  54. }
  55. newHash := BuildHash(token, appKey)
  56. if newHash != token.Hash {
  57. cherryLogger.Warnf("hash validate fail. newHash = %s, token = %s", token)
  58. return code.AccountTokenValidateError, false
  59. }
  60. return code.OK, true
  61. }
  62. func BuildHash(t *Token, appKey string) string {
  63. value := fmt.Sprintf(hashFormat, t.PID, t.OpenID, t.Timestamp)
  64. return cherryCrypto.MD5(value + appKey)
  65. }