Analyse des fonctionnalités pour l'authentification invité
Dans le développement d'un serveur de jeu Mahjong, l'authentification invité permet aux utilisateurs de s'identifier sans compte préalable, généralement via un identifiant unique comme l'IMEI d'un appareil. Ce processus implique la vérification de l'état d'activation, la création d'un utilisateur si nécessaire, et la gestion des sessions.
Points d'API pour l'authentification invité
Deux endpoints principaux sont nécessaires : l'un pour interroger si l'authentification invité est activée, et l'autre pour effectuer la connexion.
Interrogation de l'état d'activation
Cet endpoint vérifie la configuration du serveur pour détemriner si l'authentification invité est autorisée pour un canal et une application spécifiques.
POST /v1/user/login/query HTTP/1.1
Content-Type: application/json
{
"applicationId": "testApp",
"channel": "mobile"
}
La réponse indique si l'authentification invité est active :
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": 0,
"guestEnabled": true
}
Connexion invité
Cet endpoint gère la connexion des invités en créant ou récupérant un utilisateur basé sur l'identifiant de l'appareil.
POST /v1/user/login/guest HTTP/1.1
Content-Type: application/json
{
"applicationId": "testApp",
"channel": "mobile",
"deviceId": "a1b2c3d4e5f6"
}
La réponse contient les détails de l'utilisateur et la configuration du client :
{
"code": 0,
"username": "Guest_123",
"userId": 1001,
"avatarUrl": "https://example.com/avatar.png",
"virtualCurrency": 10,
"gender": 1,
"ipAddress": "192.168.1.100",
"port": 45678,
"clientConfig": {
"appVersion": "2.0.0",
"updateLinks": {
"android": "https://example.com/app.apk",
"ios": "https://example.com/app.ipa"
},
"keepAliveInterval": 30,
"forceUpdate": false,
"shareTitle": "Jouez au Mahjong",
"shareDescription": "Un jeu de Mahjong en ligne",
"supportContacts": {
"agent1": "support1@example.com",
"agent2": "support2@example.com",
"customerService": "service@example.com"
},
"applicationKey": "appSecretKey"
},
"notifications": ["Bienvenue dans le jeu!"],
"clubs": []
}
Logique métier détaillée
L'implémentation de l'authentification invité repose sur plusieurs étapes critiques, intégrant des vérifications de base de données et la gestion des données utilisateur.
Modèles de données
Les structures suivantes représentent les tables nécessaires dans la base de données, avec des annotations pour l'ORM utilisé (par exemple, GORM en Golang).
type Player struct {
ID int64 `gorm:"primaryKey;autoIncrement"`
EncryptionAlgo string `gorm:"type:varchar(16);not null;default:''"`
PasswordHash string `gorm:"type:varchar(64);not null;default:''"`
SaltValue string `gorm:"type:varchar(64);not null;default:''"`
AccountRole int `gorm:"type:tinyint;not null;default:1"`
AccountStatus int `gorm:"type:tinyint;not null;default:1"`
ActiveStatus int `gorm:"type:tinyint;not null;default:1"`
LastAccessTime int64 `gorm:"index;not null;default:0"`
PrivateKey string `gorm:"type:varchar(512);not null;default:''"`
PublicKey string `gorm:"type:varchar(128);not null;default:''"`
Balance int64 `gorm:"not null;default:0"`
CreationTime int64 `gorm:"index;not null;default:0"`
FirstPaymentTime int64 `gorm:"index;not null;default:0"`
DebugFlag int `gorm:"type:tinyint;not null;default:0"`
}
type RegistrationRecord struct {
RecordID int64 `gorm:"primaryKey;autoIncrement"`
PlayerID int64 `gorm:"index;not null"`
ExternalIP string `gorm:"type:varchar(40);not null;default:''"`
InternalIP string `gorm:"type:varchar(40);not null;default:''"`
DeviceIMEI string `gorm:"type:varchar(128);not null;default:''"`
OperatingSystem string `gorm:"type:varchar(20);not null;default:''"`
HardwareModel string `gorm:"type:varchar(20);not null;default:''"`
AppIdentifier string `gorm:"index;type:varchar(32);not null;default:''"`
ChannelID string `gorm:"index;type:varchar(32);not null;default:''"`
RegistrationTime int64 `gorm:"index;not null;default:0"`
RegistrationType int `gorm:"type:tinyint;not null;default:0"`
}
type SessionLog struct {
LogID int64 `gorm:"primaryKey;autoIncrement"`
PlayerID int64 `gorm:"index;not null"`
ExternalIP string `gorm:"type:varchar(40);not null;default:''"`
InternalIP string `gorm:"type:varchar(40);not null;default:''"`
HardwareModel string `gorm:"type:varchar(64);not null;default:''"`
DeviceIMEI string `gorm:"type:varchar(32);not null;default:''"`
OSVersion string `gorm:"type:varchar(64);not null;default:''"`
AppIdentifier string `gorm:"type:varchar(64);not null;default:''"`
ChannelID string `gorm:"type:varchar(32);not null;default:''"`
LoginTime int64 `gorm:"not null;default:0"`
LogoutTime int64 `gorm:"not null;default:0"`
}
Étapes de traitement
-
Vérifier si l'utilisateur invité existe déjà dans la base de données en utilisant l'identifiant de l'application et l'IMEI de l'appareil. La fonction
FindPlayerByDeviceinterroge les tables d'enregistrement et de joueur.player, err := database.FindPlayerByDevice(req.ApplicationID, req.Device.IMEI) -
Si aucun utilisateur n'est trouvé, créer un nouveau joueur avec des valeurs par défaut, comme un solde initial de 10 unités de monnaie virtuelle.
newPlayer := &Player{ AccountStatus: 1, ActiveStatus: 1, AccountRole: 2, Balance: 10, } insertErr := database.InsertPlayer(newPlayer)Ensuite, enregistrer une entrée dans la table des enregistrements pour le suivi.
registrationData := RegistrationRecord{ PlayerID: newPlayer.ID, DeviceIMEI: req.Device.IMEI, AppIdentifier: req.ApplicationID, ChannelID: req.Channel, RegistrationTime: time.Now().Unix(), RegistrationType: 5, // Type pour les comptes invités } database.InsertRegistrationRecord(®istrationData) -
Construire la réponse de connexion avec les informations du joueur, la configuration du client et les messages de notification.
response := LoginResponse{ Code: 0, Username: fmt.Sprintf("Guest_%d", player.ID), UserID: player.ID, AvatarURL: defaultAvatarURL, Balance: player.Balance, Gender: 1, IPAddress: extractIP(req.Device.Remote), Port: serverPort, ClientConfig: loadClientConfig(), Notifications: systemMessages, Clubs: emptyClubList, } -
Enregistrer la session de connexion dans la table des journaux pour l'audit.
sessionLog := SessionLog{ PlayerID: player.ID, ExternalIP: req.Device.Remote, InternalIP: req.Device.InternalIP, LoginTime: time.Now().Unix(), } database.InsertSessionLog(&sessionLog)
Structures de données pour les requêtes et réponses
Définitions des types utilisés dans le protocole de communication.
type GuestLoginRequest struct {
ApplicationID string `json:"applicationId"`
Channel string `json:"channel"`
Device DeviceInfo `json:"device"`
}
type DeviceInfo struct {
IMEI string `json:"imei"`
OS string `json:"os"`
Model string `json:"model"`
InternalIP string `json:"internalIP"`
Remote string `json:"remote"`
}
type LoginResponse struct {
Code int `json:"code"`
Username string `json:"username"`
UserID int64 `json:"userId"`
AvatarURL string `json:"avatarUrl"`
Balance int64 `json:"balance"`
Gender int `json:"gender"`
IPAddress string `json:"ipAddress"`
Port int `json:"port"`
ClientConfig ClientConfig `json:"clientConfig"`
Notifications []string `json:"notifications"`
Clubs []ClubInfo `json:"clubs"`
}
type ClientConfig struct {
AppVersion string `json:"appVersion"`
UpdateLinks map[string]string `json:"updateLinks"`
KeepAliveInterval int `json:"keepAliveInterval"`
ForceUpdate bool `json:"forceUpdate"`
ShareTitle string `json:"shareTitle"`
ShareDescription string `json:"shareDescription"`
SupportContacts map[string]string `json:"supportContacts"`
ApplicationKey string `json:"applicationKey"`
}
type ClubInfo struct {
ClubID int64 `json:"clubId"`
ClubName string `json:"clubName"`
Description string `json:"description"`
MemberCount int `json:"memberCount"`
MaxMembers int `json:"maxMembers"`
}
Cette approche garantit une authentification invité sécurisée et évolutible, intégrée dans une architecture cloud-native avec des pratiques DevOps.