├── .gitignore ├── LICENSE ├── README-en.md ├── README.md ├── config └── app.ini ├── consts ├── code.go └── message.go ├── docs ├── docs.go ├── swagger.json └── swagger.yaml ├── go.mod ├── go.sum ├── main.go ├── middleware └── jwt │ └── jwt.go ├── router ├── login.go └── router.go ├── service └── authentication │ └── auth.go ├── setting └── setting.go └── util ├── jwt.go └── response.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | .idea/ 14 | vendor/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 detectiveHLH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README-en.md: -------------------------------------------------------------------------------- 1 |

go-backend-starter

2 | 3 | [中文](./README.md) | English 4 | 5 | ## About 6 | 7 | Use Go Module as a dependency management, build Go-based web server based on Gin, use Endless to make the server restart smoothly, and use Swagger to automatically generate Api documents. 8 | 9 | ## Install 10 | 11 | ```bash 12 | git clone https://github.com/detectiveHLH/go-backend-starter.git 13 | cd go-backend-starter 14 | go get 15 | ``` 16 | 17 | ## Note 18 | 19 | - go的版本需要高于1.11 20 | - 使用goland时,需要确保Go module是Enable状态 21 | 22 | ## Usage 23 | 24 | - View [Swagger API documentation](http://localhost:8080/swagger/index.html) 25 | - View [Log in](http://localhost:8080/login?username=test&password=123) API, can get the access token for the system 26 | 27 | ## License 28 | 29 | [MIT](./LICENSE) 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

go-backend-starter

2 | 3 | 中文 | [English](./README-en.md) 4 | 5 | ## 介绍 6 | 7 | 使用Go Module作为依赖管理,基于Gin搭建Go的Web服务器,使用Endless来使服务器平滑重启,使用Swagger来自动生成Api文档。 8 | 9 | ## 安装 10 | 11 | ```bash 12 | git clone https://github.com/detectiveHLH/go-backend-starter.git 13 | cd go-backend-starter 14 | go get 15 | go run main.go 16 | ``` 17 | 18 | ## 注意 19 | 20 | - go的版本需要高于1.11 21 | - 使用goland时,需要确保Go module是Enable状态 22 | 23 | ## 使用 24 | 25 | - 查看[Swagger API文档](http://localhost:8080/swagger/index.html) 26 | - 访问[登录](http://localhost:8080/login?username=test&password=123)接口,可以获取Access Token 27 | 28 | ## 许可 29 | 30 | [MIT](./LICENSE) 31 | 32 | -------------------------------------------------------------------------------- /config/app.ini: -------------------------------------------------------------------------------- 1 | [app] 2 | JwtSecret = 233 3 | [server] 4 | Ip : localhost 5 | Port : 8080 6 | Url : 127.0.0.1:27017 7 | [database] 8 | Type = mysql 9 | User = root 10 | Password = yourpasswd 11 | Host = 127.0.0.1:3306 12 | Name = golang_test 13 | TablePrefix = golang_test_ 14 | -------------------------------------------------------------------------------- /consts/code.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | SUCCESS = 200 5 | ERROR = 500 6 | INVALID_PARAMS = 400 7 | 8 | ERROR_EXIST_TAG = 10001 9 | ERROR_EXIST_TAG_FAIL = 10002 10 | ERROR_NOT_EXIST_TAG = 10003 11 | ERROR_GET_TAGS_FAIL = 10004 12 | ERROR_COUNT_TAG_FAIL = 10005 13 | ERROR_ADD_TAG_FAIL = 10006 14 | ERROR_EDIT_TAG_FAIL = 10007 15 | ERROR_DELETE_TAG_FAIL = 10008 16 | ERROR_EXPORT_TAG_FAIL = 10009 17 | ERROR_IMPORT_TAG_FAIL = 10010 18 | 19 | ERROR_NOT_EXIST_ARTICLE = 10011 20 | ERROR_CHECK_EXIST_ARTICLE_FAIL = 10012 21 | ERROR_ADD_ARTICLE_FAIL = 10013 22 | ERROR_DELETE_ARTICLE_FAIL = 10014 23 | ERROR_EDIT_ARTICLE_FAIL = 10015 24 | ERROR_COUNT_ARTICLE_FAIL = 10016 25 | ERROR_GET_ARTICLES_FAIL = 10017 26 | ERROR_GET_ARTICLE_FAIL = 10018 27 | ERROR_GEN_ARTICLE_POSTER_FAIL = 10019 28 | 29 | ERROR_AUTH_CHECK_TOKEN_FAIL = 20001 30 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT = 20002 31 | ERROR_AUTH_TOKEN = 20003 32 | ERROR_AUTH = 20004 33 | 34 | ERROR_UPLOAD_SAVE_IMAGE_FAIL = 30001 35 | ERROR_UPLOAD_CHECK_IMAGE_FAIL = 30002 36 | ERROR_UPLOAD_CHECK_IMAGE_FORMAT = 30003 37 | ) 38 | -------------------------------------------------------------------------------- /consts/message.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | var MsgFlags = map[int]string{ 4 | SUCCESS: "ok", 5 | ERROR: "fail", 6 | INVALID_PARAMS: "请求参数错误", 7 | ERROR_EXIST_TAG: "已存在该标签名称", 8 | ERROR_EXIST_TAG_FAIL: "获取已存在标签失败", 9 | ERROR_NOT_EXIST_TAG: "该标签不存在", 10 | ERROR_GET_TAGS_FAIL: "获取所有标签失败", 11 | ERROR_COUNT_TAG_FAIL: "统计标签失败", 12 | ERROR_ADD_TAG_FAIL: "新增标签失败", 13 | ERROR_EDIT_TAG_FAIL: "修改标签失败", 14 | ERROR_DELETE_TAG_FAIL: "删除标签失败", 15 | ERROR_EXPORT_TAG_FAIL: "导出标签失败", 16 | ERROR_IMPORT_TAG_FAIL: "导入标签失败", 17 | ERROR_NOT_EXIST_ARTICLE: "该文章不存在", 18 | ERROR_ADD_ARTICLE_FAIL: "新增文章失败", 19 | ERROR_DELETE_ARTICLE_FAIL: "删除文章失败", 20 | ERROR_CHECK_EXIST_ARTICLE_FAIL: "检查文章是否存在失败", 21 | ERROR_EDIT_ARTICLE_FAIL: "修改文章失败", 22 | ERROR_COUNT_ARTICLE_FAIL: "统计文章失败", 23 | ERROR_GET_ARTICLES_FAIL: "获取多个文章失败", 24 | ERROR_GET_ARTICLE_FAIL: "获取单个文章失败", 25 | ERROR_GEN_ARTICLE_POSTER_FAIL: "生成文章海报失败", 26 | ERROR_AUTH_CHECK_TOKEN_FAIL: "Token鉴权失败", 27 | ERROR_AUTH_CHECK_TOKEN_TIMEOUT: "Token已超时", 28 | ERROR_AUTH_TOKEN: "Token生成失败", 29 | ERROR_AUTH: "Token错误", 30 | ERROR_UPLOAD_SAVE_IMAGE_FAIL: "保存图片失败", 31 | ERROR_UPLOAD_CHECK_IMAGE_FAIL: "检查图片失败", 32 | ERROR_UPLOAD_CHECK_IMAGE_FORMAT: "校验图片错误,图片格式或大小有问题", 33 | } 34 | 35 | /** 36 | 根据code返回相应的信息 37 | @param code key 38 | @return msg value 39 | */ 40 | func GetMsg(code int) string { 41 | msg, ok := MsgFlags[code] 42 | if ok { 43 | return msg 44 | } 45 | return MsgFlags[ERROR] 46 | } 47 | -------------------------------------------------------------------------------- /docs/docs.go: -------------------------------------------------------------------------------- 1 | // GENERATED BY THE COMMAND ABOVE; DO NOT EDIT 2 | // This file was generated by swaggo/swag at 3 | // 2019-06-10 11:31:59.816246 +0800 CST m=+0.051881270 4 | 5 | package docs 6 | 7 | import ( 8 | "bytes" 9 | 10 | "github.com/alecthomas/template" 11 | "github.com/swaggo/swag" 12 | ) 13 | 14 | var doc = `{ 15 | "swagger": "2.0", 16 | "info": { 17 | "description": "Go Backend Starter", 18 | "title": "Golang Gin API", 19 | "termsOfService": "https://github.com/detectiveHLH/go-backend-starter", 20 | "contact": {}, 21 | "license": {}, 22 | "version": "1.0" 23 | }, 24 | "host": "{{.Host}}", 25 | "basePath": "{{.BasePath}}", 26 | "paths": { 27 | "/login": { 28 | "get": { 29 | "produces": [ 30 | "application/json" 31 | ], 32 | "summary": "登录", 33 | "parameters": [ 34 | { 35 | "type": "string", 36 | "description": "username", 37 | "name": "username", 38 | "in": "query", 39 | "required": true 40 | }, 41 | { 42 | "type": "string", 43 | "description": "password", 44 | "name": "password", 45 | "in": "query", 46 | "required": true 47 | } 48 | ], 49 | "responses": { 50 | "200": { 51 | "description": "{\"code\":200,\"data\":{},\"msg\":\"ok\"}", 52 | "schema": { 53 | "type": "string" 54 | } 55 | } 56 | } 57 | } 58 | } 59 | } 60 | }` 61 | 62 | type swaggerInfo struct { 63 | Version string 64 | Host string 65 | BasePath string 66 | Title string 67 | Description string 68 | } 69 | 70 | // SwaggerInfo holds exported Swagger Info so clients can modify it 71 | var SwaggerInfo swaggerInfo 72 | 73 | type s struct{} 74 | 75 | func (s *s) ReadDoc() string { 76 | t, err := template.New("swagger_info").Parse(doc) 77 | if err != nil { 78 | return doc 79 | } 80 | 81 | var tpl bytes.Buffer 82 | if err := t.Execute(&tpl, SwaggerInfo); err != nil { 83 | return doc 84 | } 85 | 86 | return tpl.String() 87 | } 88 | 89 | func init() { 90 | swag.Register(swag.Name, &s{}) 91 | } 92 | -------------------------------------------------------------------------------- /docs/swagger.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "description": "Go Backend Starter", 5 | "title": "Golang Gin API", 6 | "termsOfService": "https://github.com/detectiveHLH/go-backend-starter", 7 | "contact": {}, 8 | "license": {}, 9 | "version": "1.0" 10 | }, 11 | "host": "{{.Host}}", 12 | "basePath": "{{.BasePath}}", 13 | "paths": { 14 | "/login": { 15 | "get": { 16 | "produces": [ 17 | "application/json" 18 | ], 19 | "summary": "登录", 20 | "parameters": [ 21 | { 22 | "type": "string", 23 | "description": "username", 24 | "name": "username", 25 | "in": "query", 26 | "required": true 27 | }, 28 | { 29 | "type": "string", 30 | "description": "password", 31 | "name": "password", 32 | "in": "query", 33 | "required": true 34 | } 35 | ], 36 | "responses": { 37 | "200": { 38 | "description": "{\"code\":200,\"data\":{},\"msg\":\"ok\"}", 39 | "schema": { 40 | "type": "string" 41 | } 42 | } 43 | } 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /docs/swagger.yaml: -------------------------------------------------------------------------------- 1 | basePath: '{{.BasePath}}' 2 | host: '{{.Host}}' 3 | info: 4 | contact: {} 5 | description: Go Backend Starter 6 | license: {} 7 | termsOfService: https://github.com/detectiveHLH/go-backend-starter 8 | title: Golang Gin API 9 | version: "1.0" 10 | paths: 11 | /login: 12 | get: 13 | parameters: 14 | - description: username 15 | in: query 16 | name: username 17 | required: true 18 | type: string 19 | - description: password 20 | in: query 21 | name: password 22 | required: true 23 | type: string 24 | produces: 25 | - application/json 26 | responses: 27 | "200": 28 | description: '{"code":200,"data":{},"msg":"ok"}' 29 | schema: 30 | type: string 31 | summary: 登录 32 | swagger: "2.0" 33 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/detectiveHLH/go-backend-starter 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc 7 | github.com/astaxie/beego v1.11.1 8 | github.com/dgrijalva/jwt-go v3.2.0+incompatible 9 | github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 10 | github.com/gin-contrib/sse v0.1.0 // indirect 11 | github.com/gin-gonic/gin v1.4.0 12 | github.com/go-openapi/jsonpointer v0.19.0 // indirect 13 | github.com/go-openapi/jsonreference v0.19.0 // indirect 14 | github.com/go-openapi/spec v0.19.0 // indirect 15 | github.com/go-openapi/swag v0.19.0 // indirect 16 | github.com/kr/pty v1.1.4 // indirect 17 | github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 // indirect 18 | github.com/mattn/go-isatty v0.0.8 // indirect 19 | github.com/stretchr/objx v0.2.0 // indirect 20 | github.com/swaggo/gin-swagger v1.1.0 21 | github.com/swaggo/swag v1.5.0 22 | github.com/ugorji/go v1.1.5-pre // indirect 23 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect 24 | golang.org/x/net v0.0.0-20190607181551-461777fb6f67 // indirect 25 | golang.org/x/sys v0.0.0-20190609082536-301114b31cce // indirect 26 | golang.org/x/text v0.3.2 // indirect 27 | golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 // indirect 28 | gopkg.in/ini.v1 v1.42.0 29 | ) 30 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 2 | github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= 3 | github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 4 | github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= 5 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 6 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= 7 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 8 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= 9 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 10 | github.com/astaxie/beego v1.11.1 h1:6DESefxW5oMcRLFRKi53/6exzup/IR6N4EzzS1n6CnQ= 11 | github.com/astaxie/beego v1.11.1/go.mod h1:i69hVzgauOPSw5qeyF4GVZhn7Od0yG5bbCGzmhbWxgQ= 12 | github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= 13 | github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= 14 | github.com/belogik/goes v0.0.0-20151229125003-e54d722c3aff/go.mod h1:PhH1ZhyCzHKt4uAasyx+ljRCgoezetRNf59CUtwUkqY= 15 | github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= 16 | github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= 17 | github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= 18 | github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= 19 | github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= 20 | github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= 21 | github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= 22 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 23 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 24 | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= 25 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 26 | github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 27 | github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= 28 | github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= 29 | github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg= 30 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 31 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 32 | github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 33 | github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= 34 | github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 35 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 36 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 37 | github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= 38 | github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= 39 | github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= 40 | github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= 41 | github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= 42 | github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= 43 | github.com/go-openapi/jsonpointer v0.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8= 44 | github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= 45 | github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= 46 | github.com/go-openapi/jsonreference v0.18.0 h1:oP2OUNdG1l2r5kYhrfVMXO54gWmzcfAwP/GFuHpNTkE= 47 | github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= 48 | github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk= 49 | github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= 50 | github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ= 51 | github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= 52 | github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4= 53 | github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= 54 | github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= 55 | github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= 56 | github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= 57 | github.com/go-openapi/swag v0.19.0 h1:Kg7Wl7LkTPlmc393QZQ/5rQadPhi7pBVEMZxyTi0Ii8= 58 | github.com/go-openapi/swag v0.19.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= 59 | github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= 60 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 61 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 62 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 63 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 64 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 65 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 66 | github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 67 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 68 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 69 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 70 | github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 71 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 72 | github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 73 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic= 74 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 75 | github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 76 | github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983 h1:wL11wNW7dhKIcRCHSm4sHKPWz0tt4mwBsVodG7+Xyqg= 77 | github.com/mailru/easyjson v0.0.0-20190403194419-1ea4449da983/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 78 | github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 79 | github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= 80 | github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 81 | github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= 82 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 83 | github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 84 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 85 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 86 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 87 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 88 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 89 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 90 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 91 | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 92 | github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= 93 | github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= 94 | github.com/siddontang/ledisdb v0.0.0-20181029004158-becf5f38d373/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= 95 | github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= 96 | github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= 97 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 98 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 99 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 100 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 101 | github.com/swaggo/gin-swagger v1.1.0 h1:ZI6/82S07DkkrMfGKbJhKj1R+QNTICkeAJP06pU36pU= 102 | github.com/swaggo/gin-swagger v1.1.0/go.mod h1:FQlm07YuT1glfN3hQiO11UQ2m39vOCZ/aa3WWr5E+XU= 103 | github.com/swaggo/swag v1.4.0 h1:exX5ES4CdJWCCKmVPE+FAIN66cnHeMHU3i2SCMibBZc= 104 | github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM= 105 | github.com/swaggo/swag v1.5.0 h1:haK8VG3hj+v/c8hQ4f3U+oYpkdI/26m9LAUTXHOv+2U= 106 | github.com/swaggo/swag v1.5.0/go.mod h1:+xZrnu5Ut3GcUkKAJm9spnOooIS1WB1cUOkLNPrvrE0= 107 | github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= 108 | github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= 109 | github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= 110 | github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= 111 | github.com/ugorji/go v1.1.5-pre h1:jyJKFOSEbdOc2HODrf2qcCkYOdq7zzXqA9bhW5oV4fM= 112 | github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0= 113 | github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4= 114 | github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= 115 | github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= 116 | github.com/ugorji/go/codec v1.1.5-pre h1:5YV9PsFAN+ndcCtTM7s60no7nY7eTG3LPtxhSwuxzCs= 117 | github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI= 118 | github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= 119 | github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= 120 | github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= 121 | golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 122 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 123 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 124 | golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 125 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 126 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 127 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 128 | golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 129 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 130 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= 131 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 132 | golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN2FrWp4IuCxOSyS0V00= 133 | golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 134 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 135 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 136 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 137 | golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 138 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 139 | golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 140 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 141 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 142 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 143 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 144 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 145 | golang.org/x/tools v0.0.0-20190110015856-aa033095749b h1:G5tsw1T5VA7PD7VmXyGtX/hQp3ABPSCPRKVfsdUcVxs= 146 | golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 147 | golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 148 | golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3 h1:sU3tSV6wDhWsvf9NjL0FzRjgAmYnQL5NEhdmcN16UEg= 149 | golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 150 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 151 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 152 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 153 | gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= 154 | gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= 155 | gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= 156 | gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 157 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 158 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 159 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 160 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/detectiveHLH/go-backend-starter/router" 6 | "github.com/detectiveHLH/go-backend-starter/setting" 7 | "github.com/fvbock/endless" 8 | "log" 9 | "syscall" 10 | ) 11 | 12 | // @title Go Backend Starter API 13 | // @version 1.0 14 | // @description Go Backend Starter 15 | // @termsOfService https://github.com/detectiveHLH/go-backend-starter 16 | func main() { 17 | setting.Setup() 18 | 19 | r := router.InitRouter() 20 | /** 21 | 启动服务器 22 | */ 23 | address := fmt.Sprintf("%s:%s", setting.ServerSetting.Ip, setting.ServerSetting.Port) 24 | server := endless.NewServer(address, r) 25 | server.BeforeBegin = func(add string) { 26 | log.Printf("Actual pid is %d", syscall.Getpid()) 27 | } 28 | // 处理服务器错误 29 | err := server.ListenAndServe() 30 | if err != nil { 31 | log.Printf("Server err: %v", err) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /middleware/jwt/jwt.go: -------------------------------------------------------------------------------- 1 | package jwt 2 | 3 | import ( 4 | "github.com/detectiveHLH/go-backend-starter/consts" 5 | "github.com/detectiveHLH/go-backend-starter/util" 6 | "github.com/gin-gonic/gin" 7 | "net/http" 8 | "time" 9 | ) 10 | 11 | func Jwt() gin.HandlerFunc { 12 | return func(c *gin.Context) { 13 | var code int 14 | var data interface{} 15 | 16 | code = consts.SUCCESS 17 | token := c.Query("token") 18 | if token == "" { 19 | code = consts.INVALID_PARAMS 20 | } else { 21 | claims, err := util.ParseToken(token) 22 | if err != nil { 23 | code = consts.ERROR_AUTH_CHECK_TOKEN_FAIL 24 | } else if time.Now().Unix() > claims.ExpiresAt { 25 | code = consts.ERROR_AUTH_CHECK_TOKEN_TIMEOUT 26 | } 27 | } 28 | 29 | if code != consts.SUCCESS { 30 | c.JSON(http.StatusUnauthorized, gin.H{ 31 | "code": code, 32 | "msg": consts.GetMsg(code), 33 | "data": data, 34 | }) 35 | 36 | c.Abort() 37 | return 38 | } 39 | 40 | c.Next() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /router/login.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "github.com/astaxie/beego/validation" 5 | "github.com/detectiveHLH/go-backend-starter/consts" 6 | "github.com/detectiveHLH/go-backend-starter/service/authentication" 7 | "github.com/detectiveHLH/go-backend-starter/util" 8 | "github.com/gin-gonic/gin" 9 | "net/http" 10 | ) 11 | 12 | type auth struct { 13 | Username string `valid:"Required; MaxSize(50)"` 14 | Password string `valid:"Required; MaxSize(50)"` 15 | } 16 | 17 | 18 | // @Summary 登录 19 | // @Produce json 20 | // @Param username query string true "username" 21 | // @Param password query string true "password" 22 | // @Success 200 {string} json "{"code":200,"data":{},"msg":"ok"}" 23 | // @Router /login [get] 24 | func Login(c *gin.Context) { 25 | appG := util.Gin{C: c} 26 | valid := validation.Validation{} 27 | username := c.Query("username") 28 | password := c.Query("password") 29 | 30 | a := auth{Username: username, Password: password} 31 | ok, _ := valid.Valid(&a) 32 | if !ok { 33 | //app.MarkErrors(valid.Errors) 34 | appG.Response(http.StatusOK, consts.INVALID_PARAMS, nil) 35 | return 36 | } 37 | 38 | authService := authentication.Auth{Username: username, Password: password} 39 | isExist, err := authService.Check() 40 | if err != nil { 41 | appG.Response(http.StatusOK, consts.ERROR_AUTH_CHECK_TOKEN_FAIL, nil) 42 | return 43 | } 44 | 45 | if !isExist { 46 | appG.Response(http.StatusOK, consts.ERROR_AUTH, nil) 47 | return 48 | } 49 | 50 | token, err := util.GenerateToken(username, password) 51 | if err != nil { 52 | appG.Response(http.StatusOK, consts.ERROR_AUTH_TOKEN, nil) 53 | return 54 | } 55 | 56 | appG.Response(http.StatusOK, consts.SUCCESS, map[string]string{ 57 | "token": token, 58 | }) 59 | } 60 | 61 | -------------------------------------------------------------------------------- /router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | _ "github.com/detectiveHLH/go-backend-starter/docs" 5 | "github.com/detectiveHLH/go-backend-starter/middleware/jwt" 6 | "github.com/gin-gonic/gin" 7 | ginSwagger "github.com/swaggo/gin-swagger" 8 | "github.com/swaggo/gin-swagger/swaggerFiles" 9 | ) 10 | 11 | func InitRouter() *gin.Engine { 12 | router := gin.New() 13 | 14 | router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) 15 | 16 | // 第一版API 17 | apiVersionOne := router.Group("/api/v1/") 18 | apiVersionOne.Use(jwt.Jwt()) 19 | // 定义鉴权接口 20 | router.GET("login", Login) 21 | apiVersionOne.GET("hello", func(c *gin.Context) { 22 | c.JSON(200, gin.H{ 23 | "success": true, 24 | "code": 200, 25 | "message": "This works", 26 | "data": nil, 27 | }) 28 | }) 29 | return router 30 | } 31 | -------------------------------------------------------------------------------- /service/authentication/auth.go: -------------------------------------------------------------------------------- 1 | package authentication 2 | 3 | import "fmt" 4 | 5 | type Auth struct { 6 | Username string 7 | Password string 8 | } 9 | 10 | func (a *Auth) Check() (bool, error) { 11 | userName := a.Username 12 | passWord := a.Password 13 | fmt.Println(userName, passWord) 14 | return true, nil 15 | } 16 | -------------------------------------------------------------------------------- /setting/setting.go: -------------------------------------------------------------------------------- 1 | package setting 2 | 3 | import ( 4 | "gopkg.in/ini.v1" 5 | "log" 6 | ) 7 | 8 | type App struct { 9 | JwtSecret string 10 | } 11 | type Server struct { 12 | Ip string 13 | Port string 14 | } 15 | type Database struct { 16 | Type string 17 | User string 18 | Password string 19 | Host string 20 | Name string 21 | TablePrefix string 22 | } 23 | 24 | var AppSetting = &App{} 25 | var ServerSetting = &Server{} 26 | var DatabaseSetting = &Database{} 27 | var config *ini.File 28 | 29 | func Setup() { 30 | var err error 31 | config, err = ini.Load("config/app.ini") 32 | if err != nil { 33 | log.Fatal("Fail to parse 'config/app.ini': %v", err) 34 | } 35 | mapTo("app", AppSetting) 36 | mapTo("server", ServerSetting) 37 | mapTo("database", DatabaseSetting) 38 | } 39 | 40 | func mapTo(section string, v interface{}) { 41 | err := config.Section(section).MapTo(v) 42 | if err != nil { 43 | log.Fatalf("Cfg.MapTo RedisSetting err: %v", err) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /util/jwt.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/detectiveHLH/go-backend-starter/setting" 5 | "github.com/dgrijalva/jwt-go" 6 | "time" 7 | ) 8 | 9 | var jwtSecret = []byte(setting.AppSetting.JwtSecret) 10 | 11 | type Claims struct { 12 | Username string `json:"username"` 13 | Password string `json:"password"` 14 | jwt.StandardClaims 15 | } 16 | 17 | /** 18 | 生成token 19 | @param username 用户名 string 20 | @param password 密码 string 21 | @returns token, err 22 | */ 23 | func GenerateToken(username, password string) (string, error) { 24 | nowTime := time.Now() 25 | expireTime := nowTime.Add(3 * time.Hour) 26 | claims := Claims{ 27 | username, 28 | password, 29 | jwt.StandardClaims { 30 | ExpiresAt : expireTime.Unix(), 31 | Issuer : "go-backend-starter", 32 | }, 33 | } 34 | tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 35 | token, err := tokenClaims.SignedString(jwtSecret) 36 | 37 | return token, err 38 | } 39 | 40 | /** 41 | 解析token 42 | @param token 43 | @returns token, err 44 | */ 45 | func ParseToken(token string) (*Claims, error) { 46 | tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { 47 | return jwtSecret, nil 48 | }) 49 | if tokenClaims != nil { 50 | if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid { 51 | return claims, nil 52 | } 53 | } 54 | 55 | return nil, err 56 | } -------------------------------------------------------------------------------- /util/response.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "github.com/detectiveHLH/go-backend-starter/consts" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | type Gin struct { 9 | C *gin.Context 10 | } 11 | 12 | /** 13 | 统一后端返回格式 14 | @param httpCode http状态码 15 | @param errCode 错误码 16 | @param data 返回数据 17 | */ 18 | func (g *Gin) Response(httpCode, errCode int, data interface{}) { 19 | g.C.JSON(httpCode, gin.H{ 20 | "code": httpCode, 21 | "msg": consts.GetMsg(errCode), 22 | "data": data, 23 | }) 24 | 25 | return 26 | } --------------------------------------------------------------------------------