实现 jwt、密码加密、casbin 的接入
This commit is contained in:
7
Makefile
7
Makefile
@ -1,7 +0,0 @@
|
|||||||
ROOT_DIR = $(shell pwd)
|
|
||||||
NAMESPACE = "default"
|
|
||||||
DEPLOY_NAME = "template-single"
|
|
||||||
DOCKER_NAME = "template-single"
|
|
||||||
|
|
||||||
include ./hack/hack-cli.mk
|
|
||||||
include ./hack/hack.mk
|
|
||||||
1
api/auth/v1/auth.go
Normal file
1
api/auth/v1/auth.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package v1
|
||||||
@ -1,15 +0,0 @@
|
|||||||
// =================================================================================
|
|
||||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
|
||||||
// =================================================================================
|
|
||||||
|
|
||||||
package hello
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"server/api/hello/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type IHelloV1 interface {
|
|
||||||
Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error)
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HelloReq struct {
|
|
||||||
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
|
|
||||||
}
|
|
||||||
type HelloRes struct {
|
|
||||||
g.Meta `mime:"text/html" example:"string"`
|
|
||||||
}
|
|
||||||
48
go.mod
48
go.mod
@ -1,28 +1,48 @@
|
|||||||
module server
|
module server
|
||||||
|
|
||||||
go 1.18
|
go 1.22
|
||||||
|
|
||||||
require github.com/gogf/gf/v2 v2.7.1
|
toolchain go1.24.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
github.com/casbin/casbin/v2 v2.105.0
|
||||||
|
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0
|
||||||
|
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0
|
||||||
|
github.com/gogf/gf/v2 v2.9.0
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||||
|
github.com/hailaz/gf-casbin-adapter/v2 v2.8.1
|
||||||
|
golang.org/x/crypto v0.30.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
|
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
|
||||||
|
github.com/casbin/govaluate v1.3.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||||
github.com/fatih/color v1.16.0 // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/gorilla/websocket v1.5.1 // indirect
|
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.9 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
go.opentelemetry.io/otel v1.14.0 // indirect
|
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
go.opentelemetry.io/otel v1.32.0 // indirect
|
||||||
golang.org/x/net v0.24.0 // indirect
|
go.opentelemetry.io/otel/metric v1.32.0 // indirect
|
||||||
golang.org/x/sys v0.19.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
go.opentelemetry.io/otel/trace v1.32.0 // indirect
|
||||||
|
golang.org/x/net v0.32.0 // indirect
|
||||||
|
golang.org/x/sys v0.28.0 // indirect
|
||||||
|
golang.org/x/text v0.21.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
113
go.sum
113
go.sum
@ -1,52 +1,109 @@
|
|||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
|
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
|
||||||
|
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
|
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||||
|
github.com/casbin/casbin/v2 v2.105.0 h1:dLj5P6pLApBRat9SADGiLxLZjiDPvA1bsPkyV4PGx6I=
|
||||||
|
github.com/casbin/casbin/v2 v2.105.0/go.mod h1:Ee33aqGrmES+GNL17L0h9X28wXuo829wnNUnS0edAco=
|
||||||
|
github.com/casbin/govaluate v1.3.0 h1:VA0eSY0M2lA86dYd5kPPuNZMUD9QkWnOCnavGrw9myc=
|
||||||
|
github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
|
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/gogf/gf/v2 v2.7.1 h1:Ukp7vzwh6VKnivEEx/xiMc61dL1HVZqCCHl//3GBRxc=
|
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||||
github.com/gogf/gf/v2 v2.7.1/go.mod h1:3oyGjyLHtSSo8kQ57Nj1TPdUNc0e2HS0A2J+KkXoW+I=
|
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0 h1:1f7EeD0lfPHoXfaJDSL7cxRcSRelbsAKgF3MGXY+Uyo=
|
||||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.0/go.mod h1:tToO1PjGkLIR+9DbJ0wrKicYma0H/EUHXOpwel6Dw+0=
|
||||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0 h1:EEZqu1PNRSmm+7Cqm9A/8+ObgfbMzhE1ps9Z3LD7HgM=
|
||||||
|
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.0/go.mod h1:LHrxY+2IzNTHVTPG/s5yaz1VmXbj+CQ7Hr5SeVkHiTw=
|
||||||
|
github.com/gogf/gf/v2 v2.9.0 h1:semN5Q5qGjDQEv4620VzxcJzJlSD07gmyJ9Sy9zfbHk=
|
||||||
|
github.com/gogf/gf/v2 v2.9.0/go.mod h1:sWGQw+pLILtuHmbOxoe0D+0DdaXxbleT57axOLH2vKI=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
|
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||||
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/hailaz/gf-casbin-adapter/v2 v2.8.1 h1:ZFIlfQAYmrL2Fe6/dZz6vCA5hYK0NxhnoKMQpbklgqc=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/hailaz/gf-casbin-adapter/v2 v2.8.1/go.mod h1:Jk91dRBZuMVjBMu2oQmqMRc6xuL5V+rzgHeFWvI+wlg=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
|
||||||
|
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||||
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
|
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||||
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
|
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||||
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||||
|
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||||
|
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||||
|
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||||
|
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||||
|
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
|
||||||
|
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||||
|
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@ -4,10 +4,6 @@
|
|||||||
gfcli:
|
gfcli:
|
||||||
gen:
|
gen:
|
||||||
dao:
|
dao:
|
||||||
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
- link: "mysql:root:MSms0427@tcp(127.0.0.1:3306)/arenax"
|
||||||
descriptionTag: true
|
descriptionTag: true
|
||||||
|
tablesEx: "casbin_rule"
|
||||||
docker:
|
|
||||||
build: "-a amd64 -s linux -p temp -ew"
|
|
||||||
tagPrefixes:
|
|
||||||
- my.image.pub/my-app
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
|
|
||||||
# Install/Update to the latest CLI tool.
|
|
||||||
.PHONY: cli
|
|
||||||
cli:
|
|
||||||
@set -e; \
|
|
||||||
wget -O gf \
|
|
||||||
https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \
|
|
||||||
chmod +x gf && \
|
|
||||||
./gf install -y && \
|
|
||||||
rm ./gf
|
|
||||||
|
|
||||||
|
|
||||||
# Check and install CLI tool.
|
|
||||||
.PHONY: cli.install
|
|
||||||
cli.install:
|
|
||||||
@set -e; \
|
|
||||||
gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \
|
|
||||||
echo "GoFame CLI is not installed, start proceeding auto installation..."; \
|
|
||||||
make cli; \
|
|
||||||
fi;
|
|
||||||
75
hack/hack.mk
75
hack/hack.mk
@ -1,75 +0,0 @@
|
|||||||
.DEFAULT_GOAL := build
|
|
||||||
|
|
||||||
# Update GoFrame and its CLI to latest stable version.
|
|
||||||
.PHONY: up
|
|
||||||
up: cli.install
|
|
||||||
@gf up -a
|
|
||||||
|
|
||||||
# Build binary using configuration from hack/config.yaml.
|
|
||||||
.PHONY: build
|
|
||||||
build: cli.install
|
|
||||||
@gf build -ew
|
|
||||||
|
|
||||||
# Parse api and generate controller/sdk.
|
|
||||||
.PHONY: ctrl
|
|
||||||
ctrl: cli.install
|
|
||||||
@gf gen ctrl
|
|
||||||
|
|
||||||
# Generate Go files for DAO/DO/Entity.
|
|
||||||
.PHONY: dao
|
|
||||||
dao: cli.install
|
|
||||||
@gf gen dao
|
|
||||||
|
|
||||||
# Parse current project go files and generate enums go file.
|
|
||||||
.PHONY: enums
|
|
||||||
enums: cli.install
|
|
||||||
@gf gen enums
|
|
||||||
|
|
||||||
# Generate Go files for Service.
|
|
||||||
.PHONY: service
|
|
||||||
service: cli.install
|
|
||||||
@gf gen service
|
|
||||||
|
|
||||||
|
|
||||||
# Build docker image.
|
|
||||||
.PHONY: image
|
|
||||||
image: cli.install
|
|
||||||
$(eval _TAG = $(shell git rev-parse --short HEAD))
|
|
||||||
ifneq (, $(shell git status --porcelain 2>/dev/null))
|
|
||||||
$(eval _TAG = $(_TAG).dirty)
|
|
||||||
endif
|
|
||||||
$(eval _TAG = $(if ${TAG}, ${TAG}, $(_TAG)))
|
|
||||||
$(eval _PUSH = $(if ${PUSH}, ${PUSH}, ))
|
|
||||||
@gf docker ${_PUSH} -tn $(DOCKER_NAME):${_TAG};
|
|
||||||
|
|
||||||
|
|
||||||
# Build docker image and automatically push to docker repo.
|
|
||||||
.PHONY: image.push
|
|
||||||
image.push: cli.install
|
|
||||||
@make image PUSH=-p;
|
|
||||||
|
|
||||||
|
|
||||||
# Deploy image and yaml to current kubectl environment.
|
|
||||||
.PHONY: deploy
|
|
||||||
deploy: cli.install
|
|
||||||
$(eval _TAG = $(if ${TAG}, ${TAG}, develop))
|
|
||||||
|
|
||||||
@set -e; \
|
|
||||||
mkdir -p $(ROOT_DIR)/temp/kustomize;\
|
|
||||||
cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_ENV};\
|
|
||||||
kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
|
|
||||||
kubectl apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
|
|
||||||
if [ $(DEPLOY_NAME) != "" ]; then \
|
|
||||||
kubectl patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}"; \
|
|
||||||
fi;
|
|
||||||
|
|
||||||
|
|
||||||
# Parsing protobuf files and generating go files.
|
|
||||||
.PHONY: pb
|
|
||||||
pb: cli.install
|
|
||||||
@gf gen pb
|
|
||||||
|
|
||||||
# Generate protobuf files for database tables.
|
|
||||||
.PHONY: pbentity
|
|
||||||
pbentity: cli.install
|
|
||||||
@gf gen pbentity
|
|
||||||
@ -2,12 +2,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
"github.com/gogf/gf/v2/net/ghttp"
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
"github.com/gogf/gf/v2/os/gcmd"
|
"github.com/gogf/gf/v2/os/gcmd"
|
||||||
|
"server/internal/middleware"
|
||||||
"server/internal/controller/hello"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -19,9 +17,15 @@ var (
|
|||||||
s := g.Server()
|
s := g.Server()
|
||||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||||
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
||||||
group.Bind(
|
group.Bind()
|
||||||
hello.NewV1(),
|
group.Group("/x", func(group *ghttp.RouterGroup) {
|
||||||
|
group.Middleware(
|
||||||
|
middleware.Auth,
|
||||||
|
middleware.Casbin,
|
||||||
|
middleware.Response,
|
||||||
)
|
)
|
||||||
|
group.Bind()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
s.Run()
|
s.Run()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
// =================================================================================
|
|
||||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
|
||||||
// =================================================================================
|
|
||||||
|
|
||||||
package hello
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
// =================================================================================
|
|
||||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
|
||||||
// =================================================================================
|
|
||||||
|
|
||||||
package hello
|
|
||||||
|
|
||||||
import (
|
|
||||||
"server/api/hello"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ControllerV1 struct{}
|
|
||||||
|
|
||||||
func NewV1() hello.IHelloV1 {
|
|
||||||
return &ControllerV1{}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package hello
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
|
||||||
|
|
||||||
"server/api/hello/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
|
|
||||||
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
27
internal/middleware/casbin.go
Normal file
27
internal/middleware/casbin.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
|
"server/utility/ecode"
|
||||||
|
"server/utility/myCasbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Casbin 是用于访问权限控制的中间件。
|
||||||
|
//
|
||||||
|
// 该中间件基于 Casbin 权限控制框架,校验当前用户是否有权访问指定的 URL 和请求方法。
|
||||||
|
// 用户权限从请求上下文中的 "permission" 字段获取,该字段通常由前置中间件(如 Auth)注入。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
//
|
||||||
|
// r *ghttp.Request - 当前的 HTTP 请求对象,由框架自动传入。
|
||||||
|
//
|
||||||
|
// 行为:
|
||||||
|
// - 如果权限验证未通过:终止请求,返回权限不足的错误(ecode.Denied)。
|
||||||
|
// - 如果权限验证通过:继续执行后续中间件或处理逻辑。
|
||||||
|
func Casbin(r *ghttp.Request) {
|
||||||
|
permission := r.GetCtxVar("permission").String()
|
||||||
|
if !myCasbin.GetMyCasbin().HasPermission(permission, r.URL.Path, r.Method) {
|
||||||
|
Exit(r, ecode.Denied)
|
||||||
|
}
|
||||||
|
r.Middleware.Next()
|
||||||
|
}
|
||||||
14
internal/middleware/exit.go
Normal file
14
internal/middleware/exit.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
|
"github.com/gogf/gf/v2/net/ghttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Exit(r *ghttp.Request, err error) {
|
||||||
|
r.Response.WriteJsonExit(ghttp.DefaultHandlerResponse{
|
||||||
|
Code: gerror.Code(err).Code(),
|
||||||
|
Message: gerror.Code(err).Message(),
|
||||||
|
Data: nil,
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -1 +1,7 @@
|
|||||||
package packed
|
package packed
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||||
|
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||||
|
_ "server/utility/myCasbin"
|
||||||
|
)
|
||||||
|
|||||||
3
main.go
3
main.go
@ -1,9 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "server/internal/packed"
|
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
|
_ "server/internal/packed"
|
||||||
|
|
||||||
"server/internal/cmd"
|
"server/internal/cmd"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,15 +1,28 @@
|
|||||||
# https://goframe.org/docs/web/server-config-file-template
|
# Server configuration.
|
||||||
server:
|
server:
|
||||||
address: ":8000"
|
address: ":8000"
|
||||||
openapiPath: "/api.json"
|
openapiPath: "/api.json"
|
||||||
swaggerPath: "/swagger"
|
swaggerPath: "/swagger"
|
||||||
|
|
||||||
# https://goframe.org/docs/core/glog-config
|
# Logger configuration.
|
||||||
logger:
|
logger:
|
||||||
level : "all"
|
level : "all"
|
||||||
stdout: true
|
stdout: true
|
||||||
|
|
||||||
# https://goframe.org/docs/core/gdb-config-file
|
# Database configuration.
|
||||||
database:
|
database:
|
||||||
|
logger:
|
||||||
|
level: "all"
|
||||||
|
stdout: true
|
||||||
default:
|
default:
|
||||||
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
link: "mysql:root:MSms0427@tcp(127.0.0.1:3306)/dealxuetest?loc=Local&charset=utf8mb4"
|
||||||
|
debug: true
|
||||||
|
|
||||||
|
# Redis configuration.
|
||||||
|
redis:
|
||||||
|
default:
|
||||||
|
address: "127.0.0.1:6379"
|
||||||
|
|
||||||
|
# Casbin model
|
||||||
|
casbin:
|
||||||
|
modelPath: "./manifest/config/rbac_model.conf"
|
||||||
14
manifest/config/rbac_model.conf
Normal file
14
manifest/config/rbac_model.conf
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act, desc
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)
|
||||||
@ -1,21 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: template-single
|
|
||||||
labels:
|
|
||||||
app: template-single
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: template-single
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: template-single
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name : main
|
|
||||||
image: template-single
|
|
||||||
imagePullPolicy: Always
|
|
||||||
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
resources:
|
|
||||||
- deployment.yaml
|
|
||||||
- service.yaml
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: template-single
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- port: 80
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 8000
|
|
||||||
selector:
|
|
||||||
app: template-single
|
|
||||||
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: template-single-configmap
|
|
||||||
data:
|
|
||||||
config.yaml: |
|
|
||||||
server:
|
|
||||||
address: ":8000"
|
|
||||||
openapiPath: "/api.json"
|
|
||||||
swaggerPath: "/swagger"
|
|
||||||
|
|
||||||
logger:
|
|
||||||
level : "all"
|
|
||||||
stdout: true
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: template-single
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name : main
|
|
||||||
image: template-single:develop
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
|
|
||||||
resources:
|
|
||||||
- ../../base
|
|
||||||
- configmap.yaml
|
|
||||||
|
|
||||||
patchesStrategicMerge:
|
|
||||||
- deployment.yaml
|
|
||||||
|
|
||||||
namespace: default
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
FROM loads/alpine:3.8
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# INSTALLATION
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
ENV WORKDIR /app
|
|
||||||
ADD resource $WORKDIR/
|
|
||||||
ADD ./temp/linux_amd64/main $WORKDIR/main
|
|
||||||
RUN chmod +x $WORKDIR/main
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# START
|
|
||||||
###############################################################################
|
|
||||||
WORKDIR $WORKDIR
|
|
||||||
CMD ./main
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# This shell is executed before docker build.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
15
utility/ecode/common.go
Normal file
15
utility/ecode/common.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package ecode
|
||||||
|
|
||||||
|
var (
|
||||||
|
OK = New(0, "操作成功")
|
||||||
|
Sub = New(1, "") // 自定义错误信息
|
||||||
|
Fail = New(2, "服务器内部错误")
|
||||||
|
InvalidOperation = New(3, "非法的操作请求")
|
||||||
|
Params = New(4, "请求参数错误")
|
||||||
|
Logout = New(5, "用户未登录")
|
||||||
|
Disabled = New(6, "账户已被禁用")
|
||||||
|
Denied = New(7, "没有权限执行该操作")
|
||||||
|
Auth = New(1000, "账户名或密码不正确")
|
||||||
|
Password = New(1001, "密码不正确")
|
||||||
|
EmailExist = New(1002, "该邮箱已被注册")
|
||||||
|
)
|
||||||
58
utility/ecode/ecode.go
Normal file
58
utility/ecode/ecode.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package ecode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/gogf/gf/v2/errors/gcode"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
code int
|
||||||
|
message string
|
||||||
|
sub string
|
||||||
|
params []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(code int, message string) Error {
|
||||||
|
return Error{
|
||||||
|
code: code,
|
||||||
|
message: message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Params(params ...interface{}) Error {
|
||||||
|
e.params = append(e.params, params...)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
return e.Message()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Sub(sub string) Error {
|
||||||
|
e.sub = sub
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Message() string {
|
||||||
|
if e.message != "" && len(e.params) > 0 {
|
||||||
|
e.message = fmt.Sprintf(e.message, e.params...)
|
||||||
|
}
|
||||||
|
if e.sub != "" {
|
||||||
|
if e.message != "" {
|
||||||
|
if len(e.params) > 0 {
|
||||||
|
e.message = fmt.Sprintf(e.message, e.params...)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%s", e.message, e.sub)
|
||||||
|
}
|
||||||
|
return e.sub
|
||||||
|
}
|
||||||
|
return e.message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Code() gcode.Code {
|
||||||
|
return gcode.New(e.code, e.Message(), "customer")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Detail() interface{} {
|
||||||
|
return "customer"
|
||||||
|
}
|
||||||
46
utility/encrypt/password.go
Normal file
46
utility/encrypt/password.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package utility
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EncryptPassword 使用 bcrypt 算法对明文密码进行加密。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - password: 明文密码字符串。
|
||||||
|
//
|
||||||
|
// 返回值:
|
||||||
|
// - 加密后的密码哈希(string)。
|
||||||
|
// - 可能出现的错误(error)。
|
||||||
|
//
|
||||||
|
// 示例:
|
||||||
|
//
|
||||||
|
// hashed, err := EncryptPassword("mySecret123")
|
||||||
|
// if err != nil {
|
||||||
|
// // 处理错误
|
||||||
|
// }
|
||||||
|
func EncryptPassword(password string) (string, error) {
|
||||||
|
// 使用 bcrypt 的默认成本因子(10)进行加密
|
||||||
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(hashedPassword), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComparePassword 比较明文密码与加密后的密码哈希是否匹配。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - hashedPassword: 已加密的密码哈希。
|
||||||
|
// - password: 用户输入的明文密码。
|
||||||
|
//
|
||||||
|
// 返回值:
|
||||||
|
// - 如果匹配返回 true,否则返回 false。
|
||||||
|
//
|
||||||
|
// 示例:
|
||||||
|
//
|
||||||
|
// match := ComparePassword(storedHash, "userInput")
|
||||||
|
func ComparePassword(hashedPassword, password string) bool {
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
77
utility/encrypt/phone.go
Normal file
77
utility/encrypt/phone.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package utility
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidatePhoneNumber 校验手机号格式是否为中国大陆合法手机号。
|
||||||
|
// 去除空格后匹配以 1 开头的 11 位数字,第二位为 3~9。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - phone: 需要验证的手机号字符串。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - true 表示格式合法,false 表示格式不合法。
|
||||||
|
func ValidatePhoneNumber(phone string) bool {
|
||||||
|
phone = strings.ReplaceAll(phone, " ", "")
|
||||||
|
pattern := `^1[3-9]\d{9}$`
|
||||||
|
matched, err := regexp.MatchString(pattern, phone)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptPhoneNumber 加密手机号字符串。
|
||||||
|
// 使用 bcrypt 进行加密,适合需要不可逆存储的场景。
|
||||||
|
// ⚠️ 注意:加密结果无法解密,仅能做比对用途。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - phone: 待加密的手机号(需合法)。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - 加密后的哈希字符串;如果手机号无效或加密失败,返回空字符串。
|
||||||
|
func EncryptPhoneNumber(phone string) string {
|
||||||
|
if !ValidatePhoneNumber(phone) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
hashedPhone, err := bcrypt.GenerateFromPassword([]byte(phone), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(hashedPhone)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaskPhoneNumber 对手机号进行脱敏处理。
|
||||||
|
// 中间四位将被替换为星号,以保护用户隐私。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - phone: 原始手机号字符串(需合法)。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - 脱敏后的手机号,如 138****1234;如果手机号无效,则返回原始输入。
|
||||||
|
func MaskPhoneNumber(phone string) string {
|
||||||
|
if !ValidatePhoneNumber(phone) {
|
||||||
|
return phone
|
||||||
|
}
|
||||||
|
return phone[:3] + "****" + phone[7:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComparePhoneNumber 比较明文手机号与加密后的哈希是否匹配。
|
||||||
|
// 用于验证用户输入的手机号是否与加密存储的值一致。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - hashedPhone: 使用 bcrypt 加密后的手机号哈希。
|
||||||
|
// - phone: 用户输入的明文手机号(需合法)。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - true 表示匹配成功;false 表示不匹配或格式错误。
|
||||||
|
func ComparePhoneNumber(hashedPhone, phone string) bool {
|
||||||
|
if !ValidatePhoneNumber(phone) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(hashedPhone), []byte(phone))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
115
utility/jwt/jwt.go
Normal file
115
utility/jwt/jwt.go
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"server/utility/ecode"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// secretKey 是用于签名 JWT 的密钥。应替换为更加安全的密钥并妥善保管。
|
||||||
|
secretKey = []byte("1a40c1d5b7a1b0f0f835e0b24ca292a6")
|
||||||
|
|
||||||
|
// issuer 表示签发者信息,作为 JWT 标准字段的一部分。
|
||||||
|
issuer = "arenax.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// TokenIn 表示生成 JWT 所需的输入参数。
|
||||||
|
//
|
||||||
|
// 字段:
|
||||||
|
// - UserId: 用户 ID;
|
||||||
|
// - Permission: 权限标识;
|
||||||
|
// - ExpireTime: token 过期时间(可选)。
|
||||||
|
TokenIn struct {
|
||||||
|
UserId int // 用户 ID
|
||||||
|
Permission string // 权限标识
|
||||||
|
ExpireTime time.Duration // 令牌有效期
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenOut 表示从 JWT 中解析出的用户信息。
|
||||||
|
//
|
||||||
|
// 字段:
|
||||||
|
// - UserId: 用户 ID;
|
||||||
|
// - Permission: 权限标识;
|
||||||
|
// - JTI: JWT 的唯一标识。
|
||||||
|
TokenOut struct {
|
||||||
|
UserId int // 用户 ID
|
||||||
|
Permission string // 权限标识
|
||||||
|
JTI string // JWT 唯一标识
|
||||||
|
}
|
||||||
|
|
||||||
|
// jwtClaims 自定义 JWT 的声明体结构,嵌入标准声明字段。
|
||||||
|
jwtClaims struct {
|
||||||
|
UserId int `json:"user_id"` // 用户 ID
|
||||||
|
Permission string `json:"permission"` // 权限标识
|
||||||
|
JTI string `json:"jti"` // 唯一标识
|
||||||
|
jwt.RegisteredClaims
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateToken 生成带有自定义权限和过期时间的 JWT 字符串。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - in: 包含用户 ID、权限、过期时间等信息的 TokenIn 对象。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - 生成的 JWT 字符串;
|
||||||
|
// - 若出错则返回错误信息。
|
||||||
|
func GenerateToken(in *TokenIn) (string, error) {
|
||||||
|
expire := in.ExpireTime
|
||||||
|
if expire <= 0 {
|
||||||
|
expire = 2 * time.Hour
|
||||||
|
}
|
||||||
|
|
||||||
|
claims := jwtClaims{
|
||||||
|
UserId: in.UserId,
|
||||||
|
Permission: in.Permission,
|
||||||
|
JTI: uuid.NewString(),
|
||||||
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(expire)),
|
||||||
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||||
|
Issuer: issuer,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
return token.SignedString(secretKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseToken 解析并验证 JWT 字符串并返回对应的用户信息。
|
||||||
|
// 自动去除开头的 "Bearer " 前缀。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - tokenString: 需要解析的 JWT 字符串。
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - 解析后的 TokenOut 对象;
|
||||||
|
// - 若失败则返回相应的错误信息。
|
||||||
|
func ParseToken(tokenString string) (*TokenOut, error) {
|
||||||
|
if strings.HasPrefix(tokenString, "Bearer ") {
|
||||||
|
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return secretKey, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, ecode.Fail.Sub("解析 token 出现异常")
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := token.Claims.(*jwtClaims)
|
||||||
|
if !ok || !token.Valid {
|
||||||
|
return nil, ecode.InvalidOperation.Sub("无效的 Token")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TokenOut{
|
||||||
|
UserId: claims.UserId,
|
||||||
|
Permission: claims.Permission,
|
||||||
|
JTI: claims.JTI,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
64
utility/myCasbin/casbin.go
Normal file
64
utility/myCasbin/casbin.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package myCasbin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/glog"
|
||||||
|
"github.com/hailaz/gf-casbin-adapter/v2"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type myCasbin struct {
|
||||||
|
*casbin.Enforcer
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
instance *myCasbin
|
||||||
|
once sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ctx := context.Background()
|
||||||
|
once.Do(func() {
|
||||||
|
modelPath := g.Config().MustGet(ctx, "casbin.modelPath").String()
|
||||||
|
enforcer, err := casbin.NewEnforcer(modelPath, adapter.NewAdapter(
|
||||||
|
adapter.Options{
|
||||||
|
GDB: g.DB(),
|
||||||
|
FieldName: &adapter.FieldName{PType: "p_type"},
|
||||||
|
},
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf(ctx, "init casbin error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = &myCasbin{Enforcer: enforcer}
|
||||||
|
})
|
||||||
|
glog.Infof(ctx, "init casbin success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMyCasbin() *myCasbin {
|
||||||
|
if instance == nil {
|
||||||
|
panic("casbin not init")
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPermission 判断给定的权限标识是否拥有访问指定 URL 和方法的权限。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - permission: 权限标识(如角色名或用户 ID)
|
||||||
|
// - url: 请求的路径(如 "/api/user/list")
|
||||||
|
// - method: HTTP 请求方法(如 "GET", "POST")
|
||||||
|
//
|
||||||
|
// 返回:
|
||||||
|
// - access: 如果有权限则为 true;否则为 false。
|
||||||
|
// - 若校验过程中发生错误,将记录日志并返回 false。
|
||||||
|
func (m *myCasbin) HasPermission(permission, url, method string) (access bool) {
|
||||||
|
enforce, err := m.Enforcer.Enforce(permission, url, method)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf(context.Background(), "enforce error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return enforce
|
||||||
|
}
|
||||||
32
utility/openid.go
Normal file
32
utility/openid.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package utility
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenerateUserID 根据传入的用户类型生成唯一的用户ID。
|
||||||
|
// 用户ID格式为:<PREFIX>_<16位数字字符串>,例如:QQ_2025052712345678。
|
||||||
|
// 前缀由 userType 参数指定(例如 "qq"、"wx"),自动转换为大写。
|
||||||
|
// 数字部分由当前时间戳与随机数拼接而成,确保唯一性。
|
||||||
|
//
|
||||||
|
// 参数:
|
||||||
|
// - userType: 用户类型,如 "qq" 或 "wx"
|
||||||
|
//
|
||||||
|
// 返回值:
|
||||||
|
// - string: 格式为 <大写前缀>_<16位唯一数字> 的用户ID
|
||||||
|
func GenerateUserID(userType string) string {
|
||||||
|
prefix := strings.ToUpper(userType)
|
||||||
|
|
||||||
|
timestamp := fmt.Sprintf("%d", time.Now().UnixNano())
|
||||||
|
core := timestamp[:12]
|
||||||
|
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
suffix := fmt.Sprintf("%04d", rand.Intn(10000))
|
||||||
|
|
||||||
|
idNum := core + suffix
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s_%s", prefix, idNum)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user