XGoServer — базовая, модульная, безопасная и надежная серверная среда.

Go сервер Android
XGoServer — базовая, модульная, безопасная и надежная серверная среда.

Автор: Линь Гуаньхун / Призраки под рукой

Самородки: https://juejin.cn/user/1785262612681997

Блог: http://www.cnblogs.com/linguanh/

Гитхаб: https://github.com/af913337456/

Облачная колонка Tencent: https://cloud.tencent.com/developer/user/1148436/activities


Базовая, модульная, безопасная и надежная серверная структура

Адрес в открытом доступе:GitHub.com/afan913337456…

Вступительная статья к первому изданию:XGoServer, серверная структура, основанная на xorm.


Недавно добавленный модуль

  • Пользовательский интерфейс маршрутизации
  • Модуль токена,jwt
  • модуль шифрования и дешифрования,cipher-AES, вы можете расширить другие
  • Пример модульного теста, соответствующий каждому модулю

общий

  • настраиваемый интерфейс маршрутизации
  • Модуль токена,jwt
  • модуль шифрования и дешифрования,cipher-AES, вы можете расширить другие
  • лог модуль,alecthomas/log4go
  • модуль маршрутизации,gorilla/mux
  • Принятие жесткого хранилища / мягкого хранилищаxormРамка
  • Интеграция общих структур выходных данных на стороне сервера, таких как json
  • Пример модульного теста, соответствующий каждому модулю

настраиваемый интерфейс маршрутизации

requireTokenОпределяет, требуется ли этот маршрутtokenпроверять

TokenDataчто мы собираемся объединитьtokenструктура данных внутриstruct

type Context struct {
	TokenData TokenData
	TokenStr  string  	`json:"tokenStr"`
	IpAddress string  	`json:"ipAddress"`  // client 的 ip
	RoutePath string  	`json:"routePath"`
}
type XHandler struct {
	handleFunc   func(*Context, http.ResponseWriter, *http.Request)
	requireToken bool
}
func (x XHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)  {
	tokenStr := r.Header.Get(TokenAuth)
	c := &Context{}
	c.IpAddress = util.GetIpAddress(r)
	c.RoutePath = r.URL.Path
	if x.requireToken {
		tokenData,err := ParseToken(tokenStr) // 使用 token 模块进行解析
		if err != nil {
			util.RenderJson(w,util.GetCommonErr(err.Error()))
			return
		}
		c.TokenData = *tokenData
		c.TokenStr  = tokenStr
		// util.RenderJson(w,c)
		x.handleFunc(c,w,r)
		return
	}
	// 不需要 token
	util.LogInterface(c)
	x.handleFunc(c,w,r)
}

Применение

  • router.Handle("/get1",core.ApiNormalHandler(getToken)).Methods("GET")
  • router.Handle("/get2",core.ApiRequestTokenHandler(handleToken)).Methods("GET")
  • Для использования с:
router.Handle("/getToken",core.ApiNormalHandler(getToken)).Methods("GET")
router.Handle("/handleToken",core.ApiRequestTokenHandler(handleToken)).Methods("GET")
router.HandleFunc("/enc",encOutput).Methods("GET")
router.HandleFunc("/dec",decOutput).Methods("POST")

Примеры коллекции

  • Вывод json напрямую клиенту
  • Логин успешно сгенерировал возврат токена
  • Прямой вывод проанализированного контекста
  • зашифрованный вывод
  • Взаимодействие с базой данных -----important

Вывод json напрямую клиенту

func main()  {
    router := new (mux.Router)
    router.HandleFunc("/",test2).Methods("GET")
    core.HttpListen(router)
}
func test2(w http.ResponseWriter,r *http.Request)  {
    // 非常简单的例子, 操作放在内部 , 可以使用 request 来获取自己的参数,再直接组织输出
    core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
    	m :=  map[string]interface{}{}
    	m["msg"] = "blow me a kiss"
    	return m
    })
}
// 结果 : {"msg":"blow me a kiss"}

Логин успешно сгенерировал возврат токена

tokenОн имеет срок годности и может быть настроен

func getToken(c *core.Context, w http.ResponseWriter, r *http.Request)  {
	core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
		tokenStr,err := core.BuildDefaultToken(func(tokenData *core.TokenData) {
			tokenData.UserId = "123456"  // 用户 id
			tokenData.Roles  = "normal"  // 用户角色
		})
		if err != nil {
			return util.GetCommonErr(err.Error())
		}
		return util.GetCommonSuccess(tokenStr)
	})
}
结果:
{
    "msg": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDU2Iiwicm9sZXMiOiJub3JtYWwiLCJwcm9wcyI6bnVsbCwiZXhwIjoxNTE5MDA2Njg4LCJpYXQiOjE1MTkwMDY2Mjh9.NsBsQ3xpOJNZUXO5Dc-Yk4p4m6p4EeDWgEfc5BaNKd4",
    "ret": "success"
}

Прямой вывод проанализированного контекста

tokenStr — переменная контекста.

Метод handleToken предназначен дляApiRequestTokenHandler

func handleToken(c *core.Context, w http.ResponseWriter, r *http.Request)  {
	util.RenderJson(w,context)
}

вывод зашифрованных данных

type IEncrypt interface {
	AesEncrypt(origData, key []byte) ([]byte, error)   // 加密
	AesDecrypt(encrypted, key []byte) ([]byte, error)  // 解密
}
// 加密输出
func encOutput(w http.ResponseWriter, r *http.Request)  {
	core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
		d := "狗年平安"
		aes := encrypt.DefaultAES{}
		return util.GetCommonSuccess(aes.AesEncryptStr(d))
	})
}
输出:
{
    "msg": "\ufffd\u0002\ufffd\u001eu\ufffd\u001c\ufffd\u0013m\ufffdM\\\ufffd\ufffd\u0011",
    "ret": "success"
}

Взаимодействовать с базой данных

func test3(w http.ResponseWriter,r *http.Request)  {
	core.HandlerMapWithOutputJson(w, func() map[string]interface{} {
		// 插入一条评论
		item := &model.Comment{
			Id	:util.NewId(),         // 评论 id
			UserId	:"123456",             // 评论人 id
			Name	:"LinGuanHong",        // 评论人名称
			Content	:"hello word",         // 评论内容
		}
		affect,_ := core.Engine.Insert(item)  // 执行插入,传入 struct 引用
		m :=  map[string]interface{}{}
		if affect > 0 {
			m["ret"] = "insert success"
			comments := make([]model.Comment, 0)
			core.Engine.Find(&comments)   // select 出来,获取所有评论输出
			m["msg"] = comments
		}else{
			m["ret"] = "insert failed"
		}
		return m
	})
}

输出的结果是:
{
  "msg": [
    {
      "id": "1kubpgh9pprrucy11e456fyytw",
      "UserId": "123456",
      "name": "LinGuanHong",
      "content": "hello word"
    }
  ],
  "ret": "insert success"
}

Вышеуказанные функции можно использовать в сочетании для обеспечения надежной безопасности. Кроме того, его можно комбинировать с маршрутизацией на уровне https.