Visitor login authentication of the actual business code
series
- Development of production-grade Mahjong game server with Golang from 0 to 1 – Part 1
- Development of production-grade Mahjong game server with Golang from 0 to 1 — Part 2
- Development of production-grade Mahjong game server with Golang from 0 to 1 — Part 3
introduce
This will be a complete, fully implemented Golang game server development tutorial series for DevOps/GitOps and cloud processes on Kubernetes.
This series of tutorials is a complete teardown of the open source Nanoserver project, designed to help you get started on the Golang server backend. Understand the essence of Golang development through practice — Share memory by communication.
The project may also involve work on Linux performance tuning (BPF related tools) and system assurance (SRE).
Step By Step development Mahjong Server
Monomer architecture
understandMahjong Server
Business – >Nano Distributed Game Server
+Micro service
Transformation.- Demo: go – mahjong – server
VSCode REST Client plug-in
If you are using VSCode as an IDE, this plugin is good:
Visitor Login Service
Business analysis
Development of production-grade Mahjong game server with Golang from 0 to 1 — Part 3
Business E – R diagram
API: Query whether visitor login is enabled
REST Client tests the API
Request:
POST http://192.168.31.125:12307/v1/user/login/query HTTP / 1.1 the content-type: application/json {"channelId": "konglai"."appId": "konglai"
}
Copy the code
The Response:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Origin, Content-Type, Authorization
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf- 8 -
Date: Sun, 07 Feb 2021 15:00:16 GMT
Content-Length: 24
Connection: close
{
"code": 0."guest": true
}
Copy the code
Business logic analysis
- Relatively simple, is based on the server
configs/config.toml
File configuration to verify:
.[login]
guest = true
lists = ["test"."konglai"]...Copy the code
API: Visitor login
REST Client tests the API
Request:
POST http://127.0.0.1:12307/v1/user/login/guest HTTP / 1.1 the content-type: application/json {"channelId": "konglai"."appId": "konglai"."imei": "c0a4ce912c48a3d0b17b59e6b97f1dca"
}
Copy the code
The Response:
{
"code": 0."name": "G1"."uid": 1."headUrl": "http://wx.qlogo.cn/mmopen/s962LEwpLxhQSOnarDnceXjSxVGaibMRsvRM4EIWic0U6fQdkpqz4Vr8XS8D81QKfyYuwjwm2M2ibsFY8mia8ic51ww/0 "."fangka": 10."sex": 1."ip": "192.168.31.125"."port": 33251."playerIp": "192.168.31.125"."config": {
"version": "1.9.3"."android": "https://fir.im/tand"."ios": "https://fir.im/tios"."heartbeat": 30."forceUpdate": true."title": "To the bitter end."."desc": "Pure Sichuan play, quick and convenient handhelds, easily set up the game, anytime, anywhere to enjoy the game."."daili1": "kefuweixin01"."daili2": "kefuweixin01"."kefu1": "kefuweixin01"."appId": "xxx"."appKey": "xxx"
},
"messages": ["System news: Healthy games, no gambling."."Welcome to the game."]."clubList": []."debug": 0
}
Copy the code
Business logic analysis
DB Model
db/model/struct.go
type User struct {
Id int64
Algo string `xorm:"not null VARCHAR(16) default"`
Hash string `xorm:"not null VARCHAR(64) default"`
Salt string `xorm:"not null VARCHAR(64) default"`
Role int `xorm:"not null TINYINT(3) default 1"`
Status int `xorm:"not null TINYINT(3) default 1"`
IsOnline int `xorm:"not null TINYINT(1) default 1"`
LastLoginAt int64 `xorm:"not null index BIGINT(11) default"`
PrivKey string `xorm:"not null VARCHAR(512) default"`
PubKey string `xorm:"not null VARCHAR(128) default"`
Coin int64 `xorm:"not null BIGINT(20) default 0"`
RegisterAt int64 `xorm:"not null index BIGINT(20) default 0"`
FirstRechargeAt int64 `xorm:"not null index BIGINT(20) default 0"`
Debug int `xorm:"not null index TINYINT(1) default 0"`
}
Copy the code
The users table | describe |
---|---|
Id | On the ID |
Algo | The encryption algorithm |
Hash | Cryptographic hash |
Salt | Encryption salt |
Role | Account type (RoleTypeAdmin=1 administrator account, RoleTypeThird=2 third-party platform account) |
Status | Account status (StatusNormal=1 normal, StatusDeleted=2 deleted, StatusFreezed=3 frozen, StatusBound=4 bound) |
IsOnline | Online (UserOffline=1 Offline, UserOnline=2 Online) |
LastLoginAt | Last Login time |
PrivKey | Account certificate private key |
PubKey | Account certificate Public key |
Coin | Room card number |
RegisterAt | Registration time |
FirstRechargeAt | The first time filling |
Debug | User Information Debugging |
type Register struct {
Id int64
Uid int64 `xorm:"not null index BIGINT(20) default"`
Remote string `xorm:"not null VARCHAR(40) default"`
Ip string `xorm:"not null VARCHAR(40) default"`
Imei string `xorm:"not null VARCHAR(128) default"`
Os string `xorm:"not null VARCHAR(20) default"`
Model string `xorm:"not null VARCHAR(20) default"`
AppId string `xorm:"not null index VARCHAR(32) default"`
ChannelId string `xorm:"not null index VARCHAR(32) default"`
RegisterAt int64 `xorm:"not null index BIGINT(11) default"`
RegisterType int `xorm:"not null index TINYINT(8) default"`
}
Copy the code
User registration record form | describe |
---|---|
Id | On the ID |
Uid | The user ID |
Remote | IP networks outside |
Ip | Network IP |
Model | Hardware model |
Imei | Imei of the device |
Os | OS version number |
AppId | Application id |
ChannelId | Channel id |
RegisterAt | Registration time |
RegisterType | Registration type (RegTypeThird=5) |
type Login struct {
Id int64
Uid int64 `xorm:"not null index BIGINT(20) default"`
Remote string `xorm:"not null VARCHAR(40) default"`
Ip string `xorm:"not null VARCHAR(40) default"`
Model string `xorm:"not null VARCHAR(64) default"`
Imei string `xorm:"not null VARCHAR(32) default"`
Os string `xorm:"not null VARCHAR(64) default"`
AppId string `xorm:"not null VARCHAR(64) default"`
ChannelId string `xorm:"not null VARCHAR(32) default"`
LoginAt int64 `xorm:"not null BIGINT(11) default"`
LogoutAt int64 `xorm:"not null BIGINT(11) default"`
}
Copy the code
User login record form | describe |
---|---|
Id | On the ID |
Uid | The user ID |
Remote | IP networks outside |
Ip | Network IP |
Model | Hardware model |
Imei | Imei of the device |
Os | OS version number |
AppId | Application id |
ChannelId | Channel id |
LoginAt | The login time |
LogoutAt | The cancellation of the time |
- According to the
AppID
(Which application does the user come from
) andDevice.IMEI
(Imei of the device
) to determine whether the current visitor is registered
user, err := db.QueryGuestUser(data.AppID, data.Device.IMEI)
Copy the code
Db.QueryGuestUser, which checks whether the user exists in the register or User table.
Definitions of related protocols:
protocol/login.go
type LoginRequest struct {
AppID string `json:"appId"` // Which application the user is from
ChannelID string `json:"channelId"` // Which channel does the user come from
IMEI string `json:"imei"`
Device Device `json:"device"`
}
Copy the code
protocol/common.go
type Device struct {
IMEI string `json:"imei"` // IMEI of the device
OS string `json:"os"` / / OS version number
Model string `json:"model"` // Hardware model
IP string `json:"ip"` / / IP network
Remote string `json:"remote"` / / the network IP
}
Copy the code
- If not, a new user is generated and a user record is registered
Definitions of relevant DB constants involved:
db/const.go
const (
StatusNormal = 1 / / normal
StatusDeleted = 2 / / delete
StatusFreezed = 3 / / freeze
StatusBound = 4 / / binding
)
const (
UserOffline = 1 / / offline
UserOnline = 2 / / online
)
// The value of the role field in the Users table
const (
RoleTypeAdmin = 1 // Administrator account
RoleTypeThird = 2 // Third party platform account
)
Copy the code
Generate a new user:
const defaultCoin = 10 // The default number of room cards is 10
user = &model.User{
Status: db.StatusNormal,
IsOnline: db.UserOffline,
Role: db.RoleTypeThird,
Coin: defaultCoin,
}
db.InsertUser(user)
Copy the code
Register a user record
db.RegisterUserLog(user, data.Device, data.AppID, data.ChannelID, protocol.RegTypeThird) // Register record
Copy the code
- structure
login
The response data
Definitions of related protocols:
protocol/login.go
type LoginResponse struct {
Code int `json:"code"`
Name string `json:"name"`
Uid int64 `json:"uid"`
HeadUrl string `json:"headUrl"`
FangKa int64 `json:"fangka"`
Sex int `json:"sex"` //[0] Unknown [1] male [2] female
IP string `json:"ip"`
Port int `json:"port"`
PlayerIP string `json:"playerIp"`
Config ClientConfig `json:"config"`
Messages []string `json:"messages"`
ClubList []ClubItem `json:"clubList"`
Debug int `json:"debug"`
}
type ClientConfig struct {
Version string `json:"version"`
Android string `json:"android"`
IOS string `json:"ios"`
Heartbeat int `json:"heartbeat"`
ForceUpdate bool `json:"forceUpdate"`
Title string `json:"title"` // Share the title
Desc string `json:"desc"` // Share the description
Daili1 string `json:"daili1"`
Daili2 string `json:"daili2"`
Kefu1 string `json:"kefu1"`
AppId string `json:"appId"`
AppKey string `json:"appKey"`
}
Copy the code
protocol/club.go
type (
ClubItem struct {
Id int64 `json:"id"`
Name string `json:"name"`
Desc string `json:"desc"`
Member int `json:"member"`
MaxMember int `json:"maxMember"`
}
/ /...
)
Copy the code
- Insert the login record and return the data required by the client
device := protocol.Device{
IP: ip(r.RemoteAddr),
Remote: r.RemoteAddr,
}
db.InsertLoginLog(user.Id, device, data.AppID, data.ChannelID)
return resp, nil
Copy the code
- A picture is worth a thousand words
As for the game server login and Nano game server communication code combat, we will discuss in detail in the next chapter.