token_service.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package service
  2. import (
  3. "errors"
  4. "github.com/dgrijalva/jwt-go"
  5. "github.com/longjoy/micro-go-course/section32/model"
  6. "time"
  7. )
  8. var (
  9. ErrExpiredToken = errors.New("token is expired")
  10. )
  11. type ResourceServerTokenService interface {
  12. // 根据访问令牌获取对应的用户信息和客户端信息
  13. GetOAuth2DetailsByAccessToken(tokenValue string) (*model.OAuth2Details, error)
  14. }
  15. type DefaultTokenService struct {
  16. tokenStore TokenStore
  17. tokenEnhancer TokenEnhancer
  18. }
  19. func NewTokenService(tokenStore TokenStore, tokenEnhancer TokenEnhancer) ResourceServerTokenService {
  20. return &DefaultTokenService{
  21. tokenStore:tokenStore,
  22. tokenEnhancer:tokenEnhancer,
  23. }
  24. }
  25. func (tokenService *DefaultTokenService) GetOAuth2DetailsByAccessToken(tokenValue string) (*model.OAuth2Details, error) {
  26. accessToken, err := tokenService.tokenStore.ReadAccessToken(tokenValue)
  27. if err != nil{
  28. return nil, err
  29. }
  30. if accessToken.IsExpired(){
  31. return nil, ErrExpiredToken
  32. }
  33. return tokenService.tokenStore.ReadOAuth2Details(tokenValue)
  34. }
  35. type TokenStore interface {
  36. // 存储访问令牌
  37. StoreAccessToken(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) error
  38. // 根据令牌值获取访问令牌结构体
  39. ReadAccessToken(tokenValue string) (*model.OAuth2Token, error)
  40. // 根据令牌值获取令牌对应的客户端和用户信息
  41. ReadOAuth2Details(tokenValue string)(*model.OAuth2Details, error)
  42. // 根据客户端信息和用户信息获取访问令牌
  43. GetAccessToken(oauth2Details *model.OAuth2Details)(*model.OAuth2Token, error);
  44. // 移除存储的访问令牌
  45. RemoveAccessToken(tokenValue string) error
  46. // 存储刷新令牌
  47. StoreRefreshToken(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) error
  48. // 移除存储的刷新令牌
  49. RemoveRefreshToken(oauth2Token string) error
  50. // 根据令牌值获取刷新令牌
  51. ReadRefreshToken(tokenValue string)(*model.OAuth2Token, error)
  52. // 根据令牌值获取刷新令牌对应的客户端和用户信息
  53. ReadOAuth2DetailsForRefreshToken(tokenValue string)(*model.OAuth2Details, error)
  54. }
  55. func NewJwtTokenStore(jwtTokenEnhancer *JwtTokenEnhancer) TokenStore {
  56. return &JwtTokenStore{
  57. jwtTokenEnhancer:jwtTokenEnhancer,
  58. }
  59. }
  60. type JwtTokenStore struct {
  61. jwtTokenEnhancer *JwtTokenEnhancer
  62. }
  63. func (tokenStore *JwtTokenStore) StoreAccessToken(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) error{
  64. return nil
  65. }
  66. func (tokenStore *JwtTokenStore)ReadAccessToken(tokenValue string) (*model.OAuth2Token, error){
  67. oauth2Token, _, err := tokenStore.jwtTokenEnhancer.Extract(tokenValue)
  68. return oauth2Token, err
  69. }
  70. // 根据令牌值获取令牌对应的客户端和用户信息
  71. func (tokenStore *JwtTokenStore) ReadOAuth2Details(tokenValue string)(*model.OAuth2Details, error){
  72. _, oauth2Details, err := tokenStore.jwtTokenEnhancer.Extract(tokenValue)
  73. return oauth2Details, err
  74. }
  75. // 根据客户端信息和用户信息获取访问令牌
  76. func (tokenStore *JwtTokenStore) GetAccessToken(oauth2Details *model.OAuth2Details)(*model.OAuth2Token, error){
  77. return nil, nil
  78. }
  79. // 移除存储的访问令牌
  80. func (tokenStore *JwtTokenStore) RemoveAccessToken(tokenValue string) error {
  81. return nil
  82. }
  83. // 存储刷新令牌
  84. func (tokenStore *JwtTokenStore) StoreRefreshToken(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) error {
  85. return nil
  86. }
  87. // 移除存储的刷新令牌
  88. func (tokenStore *JwtTokenStore)RemoveRefreshToken(oauth2Token string) error {
  89. return nil
  90. }
  91. // 根据令牌值获取刷新令牌
  92. func (tokenStore *JwtTokenStore) ReadRefreshToken(tokenValue string)(*model.OAuth2Token, error){
  93. oauth2Token, _, err := tokenStore.jwtTokenEnhancer.Extract(tokenValue)
  94. return oauth2Token, err
  95. }
  96. // 根据令牌值获取刷新令牌对应的客户端和用户信息
  97. func (tokenStore *JwtTokenStore)ReadOAuth2DetailsForRefreshToken(tokenValue string)(*model.OAuth2Details, error){
  98. _, oauth2Details, err := tokenStore.jwtTokenEnhancer.Extract(tokenValue)
  99. return oauth2Details, err
  100. }
  101. type TokenEnhancer interface {
  102. // 组装 Token 信息
  103. Enhance(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) (*model.OAuth2Token, error)
  104. // 从 Token 中还原信息
  105. Extract(tokenValue string) (*model.OAuth2Token, *model.OAuth2Details, error)
  106. }
  107. type OAuth2TokenCustomClaims struct {
  108. UserDetails model.UserDetails
  109. ClientDetails model.ClientDetails
  110. RefreshToken model.OAuth2Token
  111. jwt.StandardClaims
  112. }
  113. type JwtTokenEnhancer struct {
  114. secretKey []byte
  115. }
  116. func NewJwtTokenEnhancer(secretKey string) TokenEnhancer {
  117. return &JwtTokenEnhancer{
  118. secretKey:[]byte(secretKey),
  119. }
  120. }
  121. func (enhancer *JwtTokenEnhancer) Enhance(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) (*model.OAuth2Token, error) {
  122. return enhancer.sign(oauth2Token, oauth2Details)
  123. }
  124. func (enhancer *JwtTokenEnhancer) sign(oauth2Token *model.OAuth2Token, oauth2Details *model.OAuth2Details) (*model.OAuth2Token, error) {
  125. expireTime := oauth2Token.ExpiresTime
  126. clientDetails := oauth2Details.Client
  127. userDetails := oauth2Details.User
  128. clientDetails.ClientSecret = ""
  129. userDetails.Password = ""
  130. claims := OAuth2TokenCustomClaims{
  131. UserDetails:userDetails,
  132. ClientDetails:clientDetails,
  133. StandardClaims:jwt.StandardClaims{
  134. ExpiresAt:expireTime.Unix(),
  135. Issuer:"System",
  136. },
  137. }
  138. if oauth2Token.RefreshToken != nil{
  139. claims.RefreshToken = *oauth2Token.RefreshToken
  140. }
  141. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  142. tokenValue, err := token.SignedString(enhancer.secretKey)
  143. if err != nil{
  144. return nil, err
  145. }
  146. oauth2Token.TokenValue = tokenValue
  147. oauth2Token.TokenType = "jwt"
  148. return oauth2Token, nil;
  149. }
  150. func (enhancer *JwtTokenEnhancer) Extract(tokenValue string) (*model.OAuth2Token, *model.OAuth2Details, error) {
  151. token, err := jwt.ParseWithClaims(tokenValue, &OAuth2TokenCustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
  152. return enhancer.secretKey, nil
  153. })
  154. if err != nil{
  155. return nil, nil, err
  156. }
  157. claims := token.Claims.(*OAuth2TokenCustomClaims)
  158. expiresTime := time.Unix(claims.ExpiresAt, 0)
  159. return &model.OAuth2Token{
  160. RefreshToken:&claims.RefreshToken,
  161. TokenValue:tokenValue,
  162. ExpiresTime: &expiresTime,
  163. }, &model.OAuth2Details{
  164. User:claims.UserDetails,
  165. Client:claims.ClientDetails,
  166. }, nil
  167. }