diff --git a/go.mod b/go.mod index 775765706..7b45b0048 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/openimsdk/protocol v0.0.73-alpha.12 + github.com/openimsdk/protocol v0.0.73-alpha.14 github.com/openimsdk/tools v0.0.50-alpha.97 github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 diff --git a/go.sum b/go.sum index 329a916ec..354f80189 100644 --- a/go.sum +++ b/go.sum @@ -347,8 +347,8 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/openimsdk/gomake v0.0.15-alpha.11 h1:PQudYDRESYeYlUYrrLLJhYIlUPO5x7FAx+o5El9U/Bw= github.com/openimsdk/gomake v0.0.15-alpha.11/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= -github.com/openimsdk/protocol v0.0.73-alpha.12 h1:2NYawXeHChYUeSme6QJ9pOLh+Empce2WmwEtbP4JvKk= -github.com/openimsdk/protocol v0.0.73-alpha.12/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw= +github.com/openimsdk/protocol v0.0.73-alpha.14 h1:lv9wNiPRm6G7q74TfpMobKrSfeTaBlZ+Ps3O6UFPmaE= +github.com/openimsdk/protocol v0.0.73-alpha.14/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw= github.com/openimsdk/tools v0.0.50-alpha.97 h1:6ik5w3PpgDG6VjSo3nb3FT/fxN3JX7iIARVxVu9g7VY= github.com/openimsdk/tools v0.0.50-alpha.97/go.mod h1:n2poR3asX1e1XZce4O+MOWAp+X02QJRFvhcLCXZdzRo= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index 7a8607164..381a00a63 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -18,10 +18,13 @@ import ( "context" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/common/convert" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/mcache" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" "github.com/openimsdk/open-im-server/v3/pkg/dbbuild" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" + "github.com/openimsdk/open-im-server/v3/pkg/rpccache" "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/open-im-server/v3/pkg/common/config" @@ -46,6 +49,7 @@ import ( type authServer struct { pbauth.UnimplementedAuthServer authDatabase controller.AuthDatabase + AuthLocalCache *rpccache.AuthLocalCache RegisterCenter discovery.Conn config *Config userClient *rpcli.UserClient @@ -53,11 +57,12 @@ type authServer struct { } type Config struct { - RpcConfig config.Auth - RedisConfig config.Redis - MongoConfig config.Mongo - Share config.Share - Discovery config.Discovery + RpcConfig config.Auth + RedisConfig config.Redis + MongoConfig config.Mongo + Share config.Share + LocalCacheConfig config.LocalCache + Discovery config.Discovery } func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server grpc.ServiceRegistrar) error { @@ -84,6 +89,13 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } + authConn, err := client.GetConn(ctx, config.Discovery.RpcService.Auth) + if err != nil { + return err + } + + localcache.InitLocalCache(&config.LocalCacheConfig) + pbauth.RegisterAuthServer(server, &authServer{ RegisterCenter: client, authDatabase: controller.NewAuthDatabase( @@ -93,9 +105,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg config.Share.MultiLogin, config.Share.IMAdminUser.UserIDs, ), - config: config, - userClient: rpcli.NewUserClient(userConn), - adminUserIDs: config.Share.IMAdminUser.UserIDs, + AuthLocalCache: rpccache.NewAuthLocalCache(rpcli.NewAuthClient(authConn), &config.LocalCacheConfig, rdb), + config: config, + userClient: rpcli.NewUserClient(userConn), + adminUserIDs: config.Share.IMAdminUser.UserIDs, }) return nil } @@ -121,6 +134,10 @@ func (s *authServer) GetAdminToken(ctx context.Context, req *pbauth.GetAdminToke } prommetrics.UserLoginCounter.Inc() + + // Remove local cache for the token + s.AuthLocalCache.RemoveLocalTokenCache(ctx, req.UserID, int(constant.AdminPlatformID)) + resp.Token = token resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60 return &resp, nil @@ -151,20 +168,37 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR if err != nil { return nil, err } + + // Remove local cache for the token + s.AuthLocalCache.RemoveLocalTokenCache(ctx, req.UserID, int(req.PlatformID)) + resp.Token = token resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60 return &resp, nil } +func (s *authServer) GetExistingToken(ctx context.Context, req *pbauth.GetExistingTokenReq) (*pbauth.GetExistingTokenResp, error) { + m, err := s.authDatabase.GetTokensWithoutError(ctx, req.UserID, int(req.PlatformID)) + if err != nil { + return nil, err + } + + return &pbauth.GetExistingTokenResp{ + TokenStates: convert.TokenMapDB2Pb(m), + }, nil +} + func (s *authServer) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) { claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret(s.config.Share.Secret)) if err != nil { return nil, err } - m, err := s.authDatabase.GetTokensWithoutError(ctx, claims.UserID, claims.PlatformID) + + m, err := s.AuthLocalCache.GetExistingToken(ctx, claims.UserID, claims.PlatformID) if err != nil { return nil, err } + if len(m) == 0 { isAdmin := authverify.CheckUserIsAdmin(ctx, claims.UserID) if isAdmin { diff --git a/pkg/common/cmd/auth.go b/pkg/common/cmd/auth.go index 6e59b6dc6..d624e9dae 100644 --- a/pkg/common/cmd/auth.go +++ b/pkg/common/cmd/auth.go @@ -40,6 +40,7 @@ func NewAuthRpcCmd() *AuthRpcCmd { config.RedisConfigFileName: &authConfig.RedisConfig, config.MongodbConfigFileName: &authConfig.MongoConfig, config.ShareFileName: &authConfig.Share, + config.LocalCacheConfigFileName: &authConfig.LocalCacheConfig, config.DiscoveryConfigFilename: &authConfig.Discovery, } ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap)) diff --git a/pkg/common/convert/auth.go b/pkg/common/convert/auth.go new file mode 100644 index 000000000..a0f00c8fe --- /dev/null +++ b/pkg/common/convert/auth.go @@ -0,0 +1,25 @@ +package convert + +func TokenMapDB2Pb(tokenMapDB map[string]int) map[string]int32 { + if tokenMapDB == nil { + return nil + } + + tokenMapPB := make(map[string]int32, len(tokenMapDB)) + for k, v := range tokenMapDB { + tokenMapPB[k] = int32(v) + } + return tokenMapPB +} + +func TokenMapPb2DB(tokenMapPB map[string]int32) map[string]int { + if tokenMapPB == nil { + return nil + } + + tokenMapDB := make(map[string]int, len(tokenMapPB)) + for k, v := range tokenMapPB { + tokenMapDB[k] = int(v) + } + return tokenMapDB +} \ No newline at end of file diff --git a/pkg/localcache/init.go b/pkg/localcache/init.go index d1c16f675..ad339da7c 100644 --- a/pkg/localcache/init.go +++ b/pkg/localcache/init.go @@ -15,10 +15,11 @@ package localcache import ( - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "strings" "sync" + + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" ) var ( @@ -32,6 +33,10 @@ func InitLocalCache(localCache *config.LocalCache) { Local config.CacheConfig Keys []string }{ + { + Local: localCache.Auth, + Keys: []string{cachekey.UidPidToken}, + }, { Local: localCache.User, Keys: []string{cachekey.UserInfoKey, cachekey.UserGlobalRecvMsgOptKey}, diff --git a/pkg/rpccache/auth.go b/pkg/rpccache/auth.go index 04b512baa..94e718d0c 100644 --- a/pkg/rpccache/auth.go +++ b/pkg/rpccache/auth.go @@ -4,6 +4,8 @@ import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/convert" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/protocol/auth" @@ -35,23 +37,37 @@ type AuthLocalCache struct { local localcache.Cache[[]byte] } -// 感觉有点问题 是应该保存token map,还是根据OperationID来保存一个bool +func (a *AuthLocalCache) GetExistingToken(ctx context.Context, userID string, platformID int) (val map[string]int, err error) { + resp, err := a.getExistingToken(ctx, userID, platformID) + if err != nil { + return nil, err + } + + res := convert.TokenMapPb2DB(resp.TokenStates) -// 也不应该只绑定token 是不是还得绑定其他属性 确认说是这个用户在操作的 + return res, nil +} -func (a *AuthLocalCache) ParseToken(ctx context.Context, token string) (val *auth.ParseTokenResp, err error) { - log.ZDebug(ctx, "AuthLocalCache ParseToken req", "token", token) +func (a *AuthLocalCache) getExistingToken(ctx context.Context, userID string, platformID int) (val *auth.GetExistingTokenResp, err error) { + log.ZDebug(ctx, "AuthLocalCache GetExistingToken req", "userID", userID, "platformID", platformID) defer func() { if err != nil { - log.ZError(ctx, "AuthLocalCache ParseToken error", err, "token", token, "err", err) + log.ZError(ctx, "AuthLocalCache GetExistingToken error", err, "userID", userID, "platformID", platformID) } else { - log.ZDebug(ctx, "AuthLocalCache ParseToken resp", "token", token, "val", val) + log.ZDebug(ctx, "AuthLocalCache GetExistingToken resp", "userID", userID, "platformID", platformID, "val", val) } }() - var cache cacheProto[auth.ParseTokenResp] - return cache.Unmarshal(a.local.Get(ctx, token, func(ctx context.Context) ([]byte, error) { - log.ZDebug(ctx, "AuthLocalCache ParseToken call rpc", "token", token) - return cache.Marshal(a.client.ParseToken(ctx, token)) + var cache cacheProto[auth.GetExistingTokenResp] + + return cache.Unmarshal(a.local.Get(ctx, cachekey.GetTokenKey(userID, platformID), func(ctx context.Context) ([]byte, error) { + log.ZDebug(ctx, "AuthLocalCache GetExistingToken call rpc", "userID", userID, "platformID", platformID) + return cache.Marshal(a.client.AuthClient.GetExistingToken(ctx, &auth.GetExistingTokenReq{UserID: userID, PlatformID: int32(platformID)})) })) } + +func (a *AuthLocalCache) RemoveLocalTokenCache(ctx context.Context, userID string, platformID int) { + key := cachekey.GetTokenKey(userID, platformID) + a.local.DelLocal(ctx, key) + log.ZDebug(ctx, "AuthLocalCache RemoveLocalTokenCache", "userID", userID, "platformID", platformID, "key", key) +}