token.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package dao
  2. import (
  3. "context"
  4. "crypto/sha1"
  5. "encoding/hex"
  6. "fmt"
  7. "go-common/library/cache/redis"
  8. "go-common/library/log"
  9. )
  10. const (
  11. _defaultExpiration = 10
  12. _tokenNamespace = "upload_token:"
  13. )
  14. // RequestUploadToken generates a token for subsequent upload.
  15. // Token will expire in a specific duration.
  16. func (d *Dao) RequestUploadToken(ctx context.Context, bucket, operator string, now int64) (token string, err error) {
  17. token = genToken(bucket, operator, now)
  18. conn := d.redis.Get(ctx)
  19. defer conn.Close()
  20. nsToken := namespaceToken(token)
  21. if _, err = conn.Do("SETEX", nsToken, _defaultExpiration, "1"); err != nil {
  22. log.Error("conn.Do(SETEX %s %d) failure(%v)", nsToken, _defaultExpiration, err)
  23. }
  24. return
  25. }
  26. // VerifyUploadToken verifies if a token is legal.
  27. func (d *Dao) VerifyUploadToken(ctx context.Context, token string) bool {
  28. conn := d.redis.Get(ctx)
  29. defer conn.Close()
  30. nsToken := namespaceToken(token)
  31. valid, err := redis.Bool(conn.Do("GET", nsToken))
  32. if err != nil && err != redis.ErrNil {
  33. log.Warn("conn.Do(GET %s) failure(%v)", nsToken, err)
  34. return false
  35. }
  36. return valid
  37. }
  38. func genToken(bucket, operator string, now int64) string {
  39. sha := sha1.New()
  40. sha.Write([]byte(fmt.Sprintf("i love bilibili:%s:%s:%d", bucket, operator, now)))
  41. return fmt.Sprintf("%s:%d", hex.EncodeToString(sha.Sum([]byte(""))), now)
  42. }
  43. // Avoid key collision.
  44. func namespaceToken(token string) string {
  45. return _tokenNamespace + token
  46. }