Автор: Линь Гуаньхун / Призраки под рукой
Самородки: 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"
}