mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 14:22:26 +08:00
修复多账号登录
This commit is contained in:
@@ -46,6 +46,22 @@ func NewController(dao *dao.Dao) (r *Controller) {
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *Controller) authorize() gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
// TODO auth token或其他验证方式
|
||||
ok := true
|
||||
if ok {
|
||||
context.Next()
|
||||
return
|
||||
}
|
||||
context.Abort()
|
||||
context.JSON(http.StatusOK, gin.H{
|
||||
"code": "10001",
|
||||
"msg": "没有访问权限",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) registerRouter() {
|
||||
if config.CONF.Logger.Level == "DEBUG" {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
@@ -130,6 +146,8 @@ func (c *Controller) registerRouter() {
|
||||
engine.GET("/pictures/gt/a330cf996/slice/86f9db021.png", c.slicePng)
|
||||
engine.GET("/static/ant/sprite2x.1.2.6.png", c.sprite2xPng)
|
||||
}
|
||||
engine.Use(c.authorize())
|
||||
engine.POST("/gate/token/verify", c.gateTokenVerify)
|
||||
port := config.CONF.HttpPort
|
||||
addr := ":" + strconv.Itoa(port)
|
||||
err := engine.Run(addr)
|
||||
|
||||
49
dispatch/controller/gate_controller.go
Normal file
49
dispatch/controller/gate_controller.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"hk4e/pkg/logger"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TokenVerifyReq struct {
|
||||
AccountId string `json:"accountId"`
|
||||
AccountToken string `json:"accountToken"`
|
||||
}
|
||||
|
||||
type TokenVerifyRsp struct {
|
||||
Valid bool `json:"valid"`
|
||||
Forbid bool `json:"forbid"`
|
||||
ForbidEndTime uint32 `json:"forbidEndTime"`
|
||||
PlayerID uint32 `json:"playerID"`
|
||||
}
|
||||
|
||||
func (c *Controller) gateTokenVerify(context *gin.Context) {
|
||||
tokenVerifyReq := new(TokenVerifyReq)
|
||||
err := context.ShouldBindJSON(tokenVerifyReq)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
logger.LOG.Debug("gate token verify, req: %v", tokenVerifyReq)
|
||||
accountId, err := strconv.ParseUint(tokenVerifyReq.AccountId, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
account, err := c.dao.QueryAccountByField("accountID", accountId)
|
||||
if err != nil || account == nil {
|
||||
context.JSON(http.StatusOK, &TokenVerifyRsp{
|
||||
Valid: false,
|
||||
Forbid: false,
|
||||
ForbidEndTime: 0,
|
||||
PlayerID: 0,
|
||||
})
|
||||
return
|
||||
}
|
||||
context.JSON(http.StatusOK, &TokenVerifyRsp{
|
||||
Valid: true,
|
||||
Forbid: account.Forbid,
|
||||
ForbidEndTime: uint32(account.ForbidEndTime),
|
||||
PlayerID: uint32(account.PlayerID),
|
||||
})
|
||||
}
|
||||
@@ -3,38 +3,20 @@ package controller
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"hk4e/dispatch/model"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
appConfig "hk4e/common/config"
|
||||
"hk4e/dispatch/api"
|
||||
db "hk4e/dispatch/model"
|
||||
"hk4e/pkg/endec"
|
||||
"hk4e/pkg/httpclient"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/pkg/random"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type SdkUserLoginReq struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type SdkUserLoginRsp struct {
|
||||
Code int32 `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
Data struct {
|
||||
Uid int32 `json:"uid"`
|
||||
Username string `json:"username"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func (c *Controller) apiLogin(context *gin.Context) {
|
||||
requestData := new(api.LoginAccountRequestJson)
|
||||
err := context.ShouldBindJSON(requestData)
|
||||
@@ -109,41 +91,7 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
// SDK账号登陆
|
||||
sdkUserLoginRsp, err := httpclient.Post[SdkUserLoginRsp](appConfig.CONF.Hk4e.LoginSdkUrl, &SdkUserLoginReq{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}, "")
|
||||
// TODO 测试账号
|
||||
{
|
||||
sdkUserLoginRsp = &SdkUserLoginRsp{
|
||||
Code: 0,
|
||||
Msg: "",
|
||||
AccessToken: "",
|
||||
RefreshToken: "",
|
||||
Data: struct {
|
||||
Uid int32 `json:"uid"`
|
||||
Username string `json:"username"`
|
||||
}{
|
||||
Uid: 267042405,
|
||||
Username: "FlourishingWorld",
|
||||
},
|
||||
}
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "服务器内部错误:-1"
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
if sdkUserLoginRsp.Code != 0 {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = sdkUserLoginRsp.Msg
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
// 登录成功
|
||||
// TODO SDK账号登陆
|
||||
account, err := c.dao.QueryAccountByField("username", username)
|
||||
if err != nil {
|
||||
logger.LOG.Error("query account from db error: %v", err)
|
||||
@@ -151,6 +99,13 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
||||
}
|
||||
if account == nil {
|
||||
// 注册一个原神account
|
||||
accountId, err := c.dao.GetNextAccountId()
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "服务器内部错误:-1"
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
playerID, err := c.dao.GetNextYuanShenUid()
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
@@ -158,12 +113,15 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
regAccount := &db.Account{
|
||||
Uid: uint64(sdkUserLoginRsp.Data.Uid),
|
||||
Username: username,
|
||||
PlayerID: playerID,
|
||||
Token: base64.StdEncoding.EncodeToString(random.GetRandomByte(24)),
|
||||
ComboToken: "",
|
||||
regAccount := &model.Account{
|
||||
AccountID: accountId,
|
||||
Username: username,
|
||||
Password: endec.Md5Str(password),
|
||||
PlayerID: playerID,
|
||||
Token: "",
|
||||
ComboToken: "",
|
||||
Forbid: false,
|
||||
ForbidEndTime: 0,
|
||||
}
|
||||
_, err = c.dao.InsertAccount(regAccount)
|
||||
if err != nil {
|
||||
@@ -172,25 +130,27 @@ func (c *Controller) apiLogin(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
responseData.Message = "OK"
|
||||
responseData.Data.Account.Uid = strconv.FormatInt(int64(regAccount.Uid), 10)
|
||||
responseData.Data.Account.Token = regAccount.Token
|
||||
responseData.Data.Account.Email = regAccount.Username
|
||||
} else {
|
||||
// 生产新的token
|
||||
account.Token = base64.StdEncoding.EncodeToString(random.GetRandomByte(24))
|
||||
_, err := c.dao.UpdateAccountFieldByFieldName("uid", account.Uid, "token", account.Token)
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "服务器内部错误:-4"
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
responseData.Message = "OK"
|
||||
responseData.Data.Account.Uid = strconv.FormatInt(int64(account.Uid), 10)
|
||||
responseData.Data.Account.Token = account.Token
|
||||
responseData.Data.Account.Email = account.Username
|
||||
account = regAccount
|
||||
}
|
||||
if endec.Md5Str(password) != account.Password {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "用户名或密码错误"
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
// 生产新的token
|
||||
account.Token = base64.StdEncoding.EncodeToString(random.GetRandomByte(24))
|
||||
_, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "token", account.Token)
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "服务器内部错误:-4"
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
return
|
||||
}
|
||||
responseData.Message = "OK"
|
||||
responseData.Data.Account.Uid = strconv.FormatInt(int64(account.AccountID), 10)
|
||||
responseData.Data.Account.Token = account.Token
|
||||
responseData.Data.Account.Email = account.Username
|
||||
context.JSON(http.StatusOK, responseData)
|
||||
}
|
||||
|
||||
@@ -206,7 +166,7 @@ func (c *Controller) apiVerify(context *gin.Context) {
|
||||
logger.LOG.Error("parse uid error: %v", err)
|
||||
return
|
||||
}
|
||||
account, err := c.dao.QueryAccountByField("uid", uid)
|
||||
account, err := c.dao.QueryAccountByField("accountID", uid)
|
||||
if err != nil {
|
||||
logger.LOG.Error("query account from db error: %v", err)
|
||||
return
|
||||
@@ -249,7 +209,7 @@ func (c *Controller) v2Login(context *gin.Context) {
|
||||
return
|
||||
}
|
||||
responseData := api.NewComboTokenRes()
|
||||
account, err := c.dao.QueryAccountByField("uid", uid)
|
||||
account, err := c.dao.QueryAccountByField("accountID", uid)
|
||||
if account == nil || account.Token != loginData.Token {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "token错误"
|
||||
@@ -258,7 +218,7 @@ func (c *Controller) v2Login(context *gin.Context) {
|
||||
}
|
||||
// 生成新的comboToken
|
||||
account.ComboToken = random.GetRandomByteHexStr(20)
|
||||
_, err = c.dao.UpdateAccountFieldByFieldName("uid", account.Uid, "comboToken", account.ComboToken)
|
||||
_, err = c.dao.UpdateAccountFieldByFieldName("accountID", account.AccountID, "comboToken", account.ComboToken)
|
||||
if err != nil {
|
||||
responseData.Retcode = -201
|
||||
responseData.Message = "服务器内部错误:-1"
|
||||
|
||||
@@ -2,8 +2,8 @@ package dao
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hk4e/dispatch/model"
|
||||
|
||||
dbEntity "hk4e/dispatch/model"
|
||||
"hk4e/pkg/logger"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -12,14 +12,52 @@ import (
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
||||
db := d.db.Collection("player_id_counter")
|
||||
func (d *Dao) GetNextAccountId() (uint64, error) {
|
||||
db := d.db.Collection("account_id_counter")
|
||||
find := db.FindOne(context.TODO(), bson.D{{"_id", "default"}})
|
||||
item := new(dbEntity.PlayerIDCounter)
|
||||
item := new(model.AccountIDCounter)
|
||||
err := find.Decode(item)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
item := &dbEntity.PlayerIDCounter{
|
||||
item := &model.AccountIDCounter{
|
||||
ID: "default",
|
||||
AccountID: 1,
|
||||
}
|
||||
_, err := db.InsertOne(context.TODO(), item)
|
||||
if err != nil {
|
||||
return 0, errors.New("insert new AccountID error")
|
||||
}
|
||||
return item.AccountID, nil
|
||||
} else {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
item.AccountID++
|
||||
_, err = db.UpdateOne(
|
||||
context.TODO(),
|
||||
bson.D{
|
||||
{"_id", "default"},
|
||||
},
|
||||
bson.D{
|
||||
{"$set", bson.D{
|
||||
{"AccountID", item.AccountID},
|
||||
}},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return item.AccountID, nil
|
||||
}
|
||||
|
||||
func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
||||
db := d.db.Collection("player_id_counter")
|
||||
find := db.FindOne(context.TODO(), bson.D{{"_id", "default"}})
|
||||
item := new(model.PlayerIDCounter)
|
||||
err := find.Decode(item)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
item := &model.PlayerIDCounter{
|
||||
ID: "default",
|
||||
PlayerID: 100000001,
|
||||
}
|
||||
@@ -50,7 +88,7 @@ func (d *Dao) GetNextYuanShenUid() (uint64, error) {
|
||||
return item.PlayerID, nil
|
||||
}
|
||||
|
||||
func (d *Dao) InsertAccount(account *dbEntity.Account) (primitive.ObjectID, error) {
|
||||
func (d *Dao) InsertAccount(account *model.Account) (primitive.ObjectID, error) {
|
||||
db := d.db.Collection("account")
|
||||
id, err := db.InsertOne(context.TODO(), account)
|
||||
if err != nil {
|
||||
@@ -100,7 +138,7 @@ func (d *Dao) UpdateAccountFieldByFieldName(fieldName string, fieldValue any, fi
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*dbEntity.Account, error) {
|
||||
func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*model.Account, error) {
|
||||
db := d.db.Collection("account")
|
||||
find, err := db.Find(
|
||||
context.TODO(),
|
||||
@@ -111,9 +149,9 @@ func (d *Dao) QueryAccountByField(fieldName string, fieldValue any) (*dbEntity.A
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make([]*dbEntity.Account, 0)
|
||||
result := make([]*model.Account, 0)
|
||||
for find.Next(context.TODO()) {
|
||||
item := new(dbEntity.Account)
|
||||
item := new(model.Account)
|
||||
err := find.Decode(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -24,7 +24,7 @@ func NewDao() (r *Dao) {
|
||||
return nil
|
||||
}
|
||||
r.client = client
|
||||
r.db = client.Database("gate_hk4e")
|
||||
r.db = client.Database("dispatch_hk4e")
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ import "go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
type Account struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"`
|
||||
Uid uint64 `bson:"uid"`
|
||||
AccountID uint64 `bson:"accountID"`
|
||||
Username string `bson:"username"`
|
||||
Password string `bson:"password"`
|
||||
PlayerID uint64 `bson:"playerID"`
|
||||
Token string `bson:"token"`
|
||||
ComboToken string `bson:"comboToken"`
|
||||
|
||||
6
dispatch/model/account_id_counter.go
Normal file
6
dispatch/model/account_id_counter.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type AccountIDCounter struct {
|
||||
ID string `bson:"_id"`
|
||||
AccountID uint64 `bson:"AccountID"`
|
||||
}
|
||||
@@ -11,12 +11,12 @@ type Service struct {
|
||||
// 用户密码改变
|
||||
func (f *Service) UserPasswordChange(uid uint32) bool {
|
||||
// dispatch登录态失效
|
||||
_, err := f.dao.UpdateAccountFieldByFieldName("uid", uid, "token", "")
|
||||
_, err := f.dao.UpdateAccountFieldByFieldName("accountID", uid, "token", "")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// 游戏内登录态失效
|
||||
account, err := f.dao.QueryAccountByField("uid", uid)
|
||||
account, err := f.dao.QueryAccountByField("accountID", uid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -41,16 +41,16 @@ func (f *Service) ForbidUser(info *ForbidUserInfo) bool {
|
||||
return false
|
||||
}
|
||||
// 写入账号封禁信息
|
||||
_, err := f.dao.UpdateAccountFieldByFieldName("uid", info.UserId, "forbid", true)
|
||||
_, err := f.dao.UpdateAccountFieldByFieldName("accountID", info.UserId, "forbid", true)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, err = f.dao.UpdateAccountFieldByFieldName("uid", info.UserId, "forbidEndTime", info.ForbidEndTime)
|
||||
_, err = f.dao.UpdateAccountFieldByFieldName("accountID", info.UserId, "forbidEndTime", info.ForbidEndTime)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// 游戏强制下线
|
||||
account, err := f.dao.QueryAccountByField("uid", info.UserId)
|
||||
account, err := f.dao.QueryAccountByField("accountID", info.UserId)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func (f *Service) ForbidUser(info *ForbidUserInfo) bool {
|
||||
// 解封
|
||||
func (s *Service) UnForbidUser(uid uint32) bool {
|
||||
// 解除账号封禁
|
||||
_, err := s.dao.UpdateAccountFieldByFieldName("uid", uid, "forbid", false)
|
||||
_, err := s.dao.UpdateAccountFieldByFieldName("accountID", uid, "forbid", false)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user