mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-10-25 12:42:12 +08:00
feat: implement auth local cache.
This commit is contained in:
parent
dfed1074a5
commit
8c4e69ec41
2
go.mod
2
go.mod
@ -12,7 +12,7 @@ require (
|
|||||||
github.com/gorilla/websocket v1.5.1
|
github.com/gorilla/websocket v1.5.1
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
github.com/mitchellh/mapstructure v1.5.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/openimsdk/tools v0.0.50-alpha.97
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.18.0
|
github.com/prometheus/client_golang v1.18.0
|
||||||
|
|||||||
4
go.sum
4
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/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 h1:PQudYDRESYeYlUYrrLLJhYIlUPO5x7FAx+o5El9U/Bw=
|
||||||
github.com/openimsdk/gomake v0.0.15-alpha.11/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
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.14 h1:lv9wNiPRm6G7q74TfpMobKrSfeTaBlZ+Ps3O6UFPmaE=
|
||||||
github.com/openimsdk/protocol v0.0.73-alpha.12/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
|
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 h1:6ik5w3PpgDG6VjSo3nb3FT/fxN3JX7iIARVxVu9g7VY=
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.97/go.mod h1:n2poR3asX1e1XZce4O+MOWAp+X02QJRFvhcLCXZdzRo=
|
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=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
|||||||
@ -18,10 +18,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"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"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/mcache"
|
"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/common/storage/database/mgo"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/dbbuild"
|
"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/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
@ -46,6 +49,7 @@ import (
|
|||||||
type authServer struct {
|
type authServer struct {
|
||||||
pbauth.UnimplementedAuthServer
|
pbauth.UnimplementedAuthServer
|
||||||
authDatabase controller.AuthDatabase
|
authDatabase controller.AuthDatabase
|
||||||
|
AuthLocalCache *rpccache.AuthLocalCache
|
||||||
RegisterCenter discovery.Conn
|
RegisterCenter discovery.Conn
|
||||||
config *Config
|
config *Config
|
||||||
userClient *rpcli.UserClient
|
userClient *rpcli.UserClient
|
||||||
@ -53,11 +57,12 @@ type authServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
RpcConfig config.Auth
|
RpcConfig config.Auth
|
||||||
RedisConfig config.Redis
|
RedisConfig config.Redis
|
||||||
MongoConfig config.Mongo
|
MongoConfig config.Mongo
|
||||||
Share config.Share
|
Share config.Share
|
||||||
Discovery config.Discovery
|
LocalCacheConfig config.LocalCache
|
||||||
|
Discovery config.Discovery
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryRegistry, server grpc.ServiceRegistrar) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
authConn, err := client.GetConn(ctx, config.Discovery.RpcService.Auth)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
localcache.InitLocalCache(&config.LocalCacheConfig)
|
||||||
|
|
||||||
pbauth.RegisterAuthServer(server, &authServer{
|
pbauth.RegisterAuthServer(server, &authServer{
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
authDatabase: controller.NewAuthDatabase(
|
authDatabase: controller.NewAuthDatabase(
|
||||||
@ -93,9 +105,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
config.Share.MultiLogin,
|
config.Share.MultiLogin,
|
||||||
config.Share.IMAdminUser.UserIDs,
|
config.Share.IMAdminUser.UserIDs,
|
||||||
),
|
),
|
||||||
config: config,
|
AuthLocalCache: rpccache.NewAuthLocalCache(rpcli.NewAuthClient(authConn), &config.LocalCacheConfig, rdb),
|
||||||
userClient: rpcli.NewUserClient(userConn),
|
config: config,
|
||||||
adminUserIDs: config.Share.IMAdminUser.UserIDs,
|
userClient: rpcli.NewUserClient(userConn),
|
||||||
|
adminUserIDs: config.Share.IMAdminUser.UserIDs,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -121,6 +134,10 @@ func (s *authServer) GetAdminToken(ctx context.Context, req *pbauth.GetAdminToke
|
|||||||
}
|
}
|
||||||
|
|
||||||
prommetrics.UserLoginCounter.Inc()
|
prommetrics.UserLoginCounter.Inc()
|
||||||
|
|
||||||
|
// Remove local cache for the token
|
||||||
|
s.AuthLocalCache.RemoveLocalTokenCache(ctx, req.UserID, int(constant.AdminPlatformID))
|
||||||
|
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
@ -151,20 +168,37 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove local cache for the token
|
||||||
|
s.AuthLocalCache.RemoveLocalTokenCache(ctx, req.UserID, int(req.PlatformID))
|
||||||
|
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.RpcConfig.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
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) {
|
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))
|
claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret(s.config.Share.Secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(m) == 0 {
|
if len(m) == 0 {
|
||||||
isAdmin := authverify.CheckUserIsAdmin(ctx, claims.UserID)
|
isAdmin := authverify.CheckUserIsAdmin(ctx, claims.UserID)
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
|
|||||||
@ -40,6 +40,7 @@ func NewAuthRpcCmd() *AuthRpcCmd {
|
|||||||
config.RedisConfigFileName: &authConfig.RedisConfig,
|
config.RedisConfigFileName: &authConfig.RedisConfig,
|
||||||
config.MongodbConfigFileName: &authConfig.MongoConfig,
|
config.MongodbConfigFileName: &authConfig.MongoConfig,
|
||||||
config.ShareFileName: &authConfig.Share,
|
config.ShareFileName: &authConfig.Share,
|
||||||
|
config.LocalCacheConfigFileName: &authConfig.LocalCacheConfig,
|
||||||
config.DiscoveryConfigFilename: &authConfig.Discovery,
|
config.DiscoveryConfigFilename: &authConfig.Discovery,
|
||||||
}
|
}
|
||||||
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
|
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
|
||||||
|
|||||||
25
pkg/common/convert/auth.go
Normal file
25
pkg/common/convert/auth.go
Normal file
@ -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
|
||||||
|
}
|
||||||
@ -15,10 +15,11 @@
|
|||||||
package localcache
|
package localcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -32,6 +33,10 @@ func InitLocalCache(localCache *config.LocalCache) {
|
|||||||
Local config.CacheConfig
|
Local config.CacheConfig
|
||||||
Keys []string
|
Keys []string
|
||||||
}{
|
}{
|
||||||
|
{
|
||||||
|
Local: localCache.Auth,
|
||||||
|
Keys: []string{cachekey.UidPidToken},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Local: localCache.User,
|
Local: localCache.User,
|
||||||
Keys: []string{cachekey.UserInfoKey, cachekey.UserGlobalRecvMsgOptKey},
|
Keys: []string{cachekey.UserInfoKey, cachekey.UserGlobalRecvMsgOptKey},
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"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/localcache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
"github.com/openimsdk/protocol/auth"
|
"github.com/openimsdk/protocol/auth"
|
||||||
@ -35,23 +37,37 @@ type AuthLocalCache struct {
|
|||||||
local localcache.Cache[[]byte]
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// 也不应该只绑定token 是不是还得绑定其他属性 确认说是这个用户在操作的
|
res := convert.TokenMapPb2DB(resp.TokenStates)
|
||||||
|
|
||||||
func (a *AuthLocalCache) ParseToken(ctx context.Context, token string) (val *auth.ParseTokenResp, err error) {
|
return res, nil
|
||||||
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() {
|
defer func() {
|
||||||
if err != nil {
|
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 {
|
} 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]
|
var cache cacheProto[auth.GetExistingTokenResp]
|
||||||
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.Unmarshal(a.local.Get(ctx, cachekey.GetTokenKey(userID, platformID), func(ctx context.Context) ([]byte, error) {
|
||||||
return cache.Marshal(a.client.ParseToken(ctx, token))
|
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)
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user