user.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package utils
  2. import (
  3. "errors"
  4. "git.bvbej.com/bvbej/base-golang/pkg/hash"
  5. "git.bvbej.com/bvbej/base-golang/pkg/hmac"
  6. "git.bvbej.com/bvbej/base-golang/pkg/time_parse"
  7. "time"
  8. )
  9. var _ UserToken = (*userToken)(nil)
  10. type UserToken interface {
  11. i()
  12. Generate(id uint64, platform string) (userID, token string, err error)
  13. Validate(userID, token, platform string) (id uint64, err error)
  14. }
  15. type userToken struct {
  16. hashids hash.Hash
  17. hmac hmac.HMAC
  18. ttl time.Duration
  19. }
  20. func NewUserToken(secret string, ttl time.Duration) UserToken {
  21. return &userToken{
  22. hashids: hash.New(secret, 32),
  23. hmac: hmac.New(secret),
  24. ttl: time.Minute * ttl,
  25. }
  26. }
  27. func (t *userToken) i() {}
  28. func (t *userToken) Generate(id uint64, platform string) (userID, token string, err error) {
  29. userID, err = t.hashids.HashidsEncode([]int{int(int64(id)), int(time.Now().Unix())})
  30. if err != nil {
  31. return "", "", err
  32. }
  33. token = t.hmac.Sha1ToString(userID + platform)
  34. return
  35. }
  36. func (t *userToken) Validate(userID, token, platform string) (id uint64, err error) {
  37. if t.hmac.Sha1ToString(userID+platform) != token {
  38. return id, errors.New("token invalid")
  39. }
  40. hashidsDecode, err := t.hashids.HashidsDecode(userID)
  41. if err != nil {
  42. return id, err
  43. }
  44. if len(hashidsDecode) == 2 {
  45. if time_parse.SubInLocation(time.Unix(int64(hashidsDecode[1]), 0)) > float64(t.ttl/time.Second) {
  46. return id, errors.New("token expired")
  47. }
  48. }
  49. return uint64(hashidsDecode[0]), nil
  50. }