Visitor login authentication of the actual business code

series

  1. Development of production-grade Mahjong game server with Golang from 0 to 1 – Part 1
  2. Development of production-grade Mahjong game server with Golang from 0 to 1 — Part 2
  3. 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 architectureunderstandMahjong ServerBusiness – >Nano Distributed Game Server + Micro serviceTransformation.
  • 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

  1. Relatively simple, is based on the serverconfigs/config.tomlFile 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
  1. According to theAppID(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
  1. 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
  1. structureloginThe 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
  1. 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
  1. 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.