jwt_auth.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package auth
  2. import (
  3. "encoding/json"
  4. "github.com/dgrijalva/jwt-go"
  5. "gxt-api-frame/app/errors"
  6. "time"
  7. )
  8. // TokenInfo 令牌信息
  9. type TokenInfo interface {
  10. // GetAccessToken 获取访问令牌
  11. GetAccessToken() string
  12. // GetTokenType 获取令牌类型
  13. GetTokenType() string
  14. // GetExpiresAt 获取令牌到期时间戳
  15. GetExpiresAt() int64
  16. // EncodeToJSON JSON编码
  17. EncodeToJSON() ([]byte, error)
  18. }
  19. // tokenInfo 令牌信息
  20. type tokenInfo struct {
  21. AccessToken string `json:"access_token"` // 访问令牌
  22. TokenType string `json:"token_type"` // 令牌类型
  23. ExpiresAt int64 `json:"expires_at"` // 令牌到期时间
  24. }
  25. func (t *tokenInfo) GetAccessToken() string {
  26. return t.AccessToken
  27. }
  28. func (t *tokenInfo) GetTokenType() string {
  29. return t.TokenType
  30. }
  31. func (t *tokenInfo) GetExpiresAt() int64 {
  32. return t.ExpiresAt
  33. }
  34. func (t *tokenInfo) EncodeToJSON() ([]byte, error) {
  35. return json.Marshal(t)
  36. }
  37. type options struct {
  38. signingMethod jwt.SigningMethod
  39. signingKey interface{}
  40. keyfunc jwt.Keyfunc
  41. expired int
  42. tokenType string
  43. }
  44. const defaultKey = "smartpark"
  45. var defaultOptions = options{
  46. tokenType: "Bearer",
  47. expired: 7200,
  48. signingMethod: jwt.SigningMethodHS512,
  49. signingKey: []byte(defaultKey),
  50. keyfunc: func(t *jwt.Token) (interface{}, error) {
  51. if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
  52. return nil, errors.ErrInvalidToken
  53. }
  54. return []byte(defaultKey), nil
  55. },
  56. }
  57. // SetSigningMethod 设定签名方式
  58. func SetSigningMethod(method jwt.SigningMethod) Option {
  59. return func(o *options) {
  60. o.signingMethod = method
  61. }
  62. }
  63. // SetSigningKey 设定签名key
  64. func SetSigningKey(key interface{}) Option {
  65. return func(o *options) {
  66. o.signingKey = key
  67. }
  68. }
  69. // SetKeyfunc 设定验证key的回调函数
  70. func SetKeyfunc(keyFunc jwt.Keyfunc) Option {
  71. return func(o *options) {
  72. o.keyfunc = keyFunc
  73. }
  74. }
  75. // SetExpired 设定令牌过期时长(单位秒,默认7200)
  76. func SetExpired(expired int) Option {
  77. return func(o *options) {
  78. o.expired = expired
  79. }
  80. }
  81. type Option func(*options)
  82. type JWTAuth struct {
  83. opts *options
  84. }
  85. func New(opts ...Option) *JWTAuth {
  86. o := defaultOptions
  87. for _, opt := range opts {
  88. opt(&o)
  89. }
  90. return &JWTAuth{opts: &o}
  91. }
  92. // GenerateToken 生成令牌
  93. func (a *JWTAuth) GenerateToken(userID string) (TokenInfo, error) {
  94. now := time.Now()
  95. expiresAt := now.Add(time.Duration(a.opts.expired) * time.Second).Unix()
  96. token := jwt.NewWithClaims(a.opts.signingMethod, &jwt.StandardClaims{
  97. IssuedAt: now.Unix(),
  98. ExpiresAt: expiresAt,
  99. NotBefore: now.Unix(),
  100. Subject: userID,
  101. })
  102. tokenString, err := token.SignedString(a.opts.signingKey)
  103. if err != nil {
  104. return nil, err
  105. }
  106. tokenInfo := &tokenInfo{
  107. ExpiresAt: expiresAt,
  108. TokenType: a.opts.tokenType,
  109. AccessToken: tokenString,
  110. }
  111. return tokenInfo, nil
  112. }
  113. // 解析令牌
  114. func (a *JWTAuth) parseToken(tokenString string) (*jwt.StandardClaims, error) {
  115. token, _ := jwt.ParseWithClaims(tokenString, &jwt.StandardClaims{}, a.opts.keyfunc)
  116. if !token.Valid {
  117. return nil, errors.ErrInvalidToken
  118. }
  119. return token.Claims.(*jwt.StandardClaims), nil
  120. }
  121. // ParseUserID 解析用户ID
  122. func (a *JWTAuth) ParseUserID(tokenString string) (string, error) {
  123. claims, err := a.parseToken(tokenString)
  124. if err != nil {
  125. return "", err
  126. }
  127. return claims.Subject, nil
  128. }
  129. // Auther 认证接口
  130. type Auther interface {
  131. // GenerateToken 生成令牌
  132. GenerateToken(userID string) (TokenInfo, error)
  133. // 销毁令牌
  134. //DestroyToken(accessToken string) error
  135. // ParseUserID 解析用户ID
  136. ParseUserID(accessToken string) (string, error)
  137. // 释放资源
  138. //Release() error
  139. //GenerateApiToken(userID string) (TokenInfo, error)
  140. }