feat(app): 添加 token 校验功能和用户信息获取接口
- 新增 AuthToken 方法用于校验用户 token - 在 app 接口中添加 AuthToken 方法定义 - 在 defaultApp 结构体中实现 AuthToken 方法 - 修改 GetVerifyCode、Login、Register 接口的 tags 为 user_public - 新增 /user POST 接口用于获取用户详细信息 - 在 app.pb.go 文件中新增 AuthInfoResp、AuthReq 等相关结构体定义 - 更新 proto 文件中的消息类型索引以适应新增结构体 - 新增 ClaimStrings 和 NumericDate 结构体支持 JWT 相关字段 - 新增 RegisteredClaims 结构体用于表示 JWT 声明集
This commit is contained in:
parent
538f6e7e39
commit
67eca4d18e
38
api/app.json
38
api/app.json
|
|
@ -22,7 +22,7 @@
|
||||||
"post": {
|
"post": {
|
||||||
"description": "GetVerifyCode | 获取验证码",
|
"description": "GetVerifyCode | 获取验证码",
|
||||||
"tags": [
|
"tags": [
|
||||||
"user"
|
"user_public"
|
||||||
],
|
],
|
||||||
"summary": "GetVerifyCode | 获取验证码",
|
"summary": "GetVerifyCode | 获取验证码",
|
||||||
"operationId": "GetVerifyCode",
|
"operationId": "GetVerifyCode",
|
||||||
|
|
@ -68,7 +68,7 @@
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Login | 登录",
|
"description": "Login | 登录",
|
||||||
"tags": [
|
"tags": [
|
||||||
"user"
|
"user_public"
|
||||||
],
|
],
|
||||||
"summary": "Login | 登录",
|
"summary": "Login | 登录",
|
||||||
"operationId": "Login",
|
"operationId": "Login",
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Register | 注册",
|
"description": "Register | 注册",
|
||||||
"tags": [
|
"tags": [
|
||||||
"user"
|
"user_public"
|
||||||
],
|
],
|
||||||
"summary": "Register | 注册",
|
"summary": "Register | 注册",
|
||||||
"operationId": "Register",
|
"operationId": "Register",
|
||||||
|
|
@ -119,6 +119,34 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/user": {
|
||||||
|
"post": {
|
||||||
|
"description": "Get userInfo detail by ID | 获取用户信息",
|
||||||
|
"tags": [
|
||||||
|
"user"
|
||||||
|
],
|
||||||
|
"summary": "Get userInfo detail by ID | 获取用户信息",
|
||||||
|
"operationId": "GetUserInfoById",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/IDReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "UserInfo",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/UserInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
|
@ -868,6 +896,10 @@
|
||||||
},
|
},
|
||||||
"x-go-package": "mingyang-admin-app-api/internal/types"
|
"x-go-package": "mingyang-admin-app-api/internal/types"
|
||||||
},
|
},
|
||||||
|
"UserInfoReq": {
|
||||||
|
"type": "object",
|
||||||
|
"x-go-package": "mingyang-admin-app-api/internal/types"
|
||||||
|
},
|
||||||
"VerifyCodeReq": {
|
"VerifyCodeReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RegisterResp{
|
RegisterResp{
|
||||||
// token信息
|
// token信息
|
||||||
AuthToken *AuthToken `json:"authToken,optional"`
|
AuthToken *AuthToken `json:"authToken,optional"`
|
||||||
|
|
@ -109,13 +108,16 @@ type (
|
||||||
AuthToken *AuthToken
|
AuthToken *AuthToken
|
||||||
UserInfo *UserInfo
|
UserInfo *UserInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserInfoReq{
|
||||||
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@server (
|
@server (
|
||||||
jwt: Auth
|
group: user_public
|
||||||
group: user
|
|
||||||
middleware: Authority
|
|
||||||
)
|
)
|
||||||
|
|
||||||
service App {
|
service App {
|
||||||
// GetVerifyCode | 获取验证码
|
// GetVerifyCode | 获取验证码
|
||||||
@handler getVerifyCode
|
@handler getVerifyCode
|
||||||
|
|
@ -128,3 +130,15 @@ service App {
|
||||||
post /login (LoginReq) returns (LoginResp)
|
post /login (LoginReq) returns (LoginResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@server (
|
||||||
|
group: user
|
||||||
|
middleware: Authority
|
||||||
|
)
|
||||||
|
|
||||||
|
service App {
|
||||||
|
// Get userInfo detail by ID | 获取用户信息
|
||||||
|
@handler getUserInfoById
|
||||||
|
post /user (IDReq) returns (UserInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ Host: 0.0.0.0
|
||||||
Port: 9902
|
Port: 9902
|
||||||
Timeout: 4000
|
Timeout: 4000
|
||||||
|
|
||||||
|
|
||||||
CROSConf:
|
CROSConf:
|
||||||
Address: '*'
|
Address: '*'
|
||||||
|
|
||||||
|
|
@ -29,6 +28,9 @@ AppRpc:
|
||||||
Target: 127.0.0.1:9901
|
Target: 127.0.0.1:9901
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
JWTConf:
|
||||||
|
AccessSecret: KdAj3ZnmHpVvGKBthWXmTNPRcdZaWP7cnbsvmJSYRadN8PebaaAQENVKDD6WCm
|
||||||
|
|
||||||
|
|
||||||
I18nConf:
|
I18nConf:
|
||||||
Dir:
|
Dir:
|
||||||
|
|
@ -3,6 +3,8 @@ module mingyang-admin-app-api
|
||||||
go 1.25.3
|
go 1.25.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||||
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/redis/go-redis/v9 v9.16.0
|
github.com/redis/go-redis/v9 v9.16.0
|
||||||
github.com/saas-mingyang/mingyang-admin-common v0.3.3
|
github.com/saas-mingyang/mingyang-admin-common v0.3.3
|
||||||
github.com/zeromicro/go-zero v1.9.1
|
github.com/zeromicro/go-zero v1.9.1
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
|
@ -149,6 +151,8 @@ github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7s
|
||||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,9 @@ type Config struct {
|
||||||
CROSConf config.CROSConf
|
CROSConf config.CROSConf
|
||||||
I18nConf i18n.Conf
|
I18nConf i18n.Conf
|
||||||
AppRpc zrpc.RpcClientConf
|
AppRpc zrpc.RpcClientConf
|
||||||
|
Auth JWTConfig `json:"JWTConf"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type JWTConfig struct {
|
||||||
|
AccessSecret string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
base "mingyang-admin-app-api/internal/handler/base"
|
base "mingyang-admin-app-api/internal/handler/base"
|
||||||
user "mingyang-admin-app-api/internal/handler/user"
|
user "mingyang-admin-app-api/internal/handler/user"
|
||||||
|
user_public "mingyang-admin-app-api/internal/handler/user_public"
|
||||||
"mingyang-admin-app-api/internal/svc"
|
"mingyang-admin-app-api/internal/svc"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
|
@ -24,27 +25,36 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/get/verifyCode",
|
||||||
|
Handler: user_public.GetVerifyCodeHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/register",
|
||||||
|
Handler: user_public.RegisterHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/login",
|
||||||
|
Handler: user_public.LoginHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
server.AddRoutes(
|
server.AddRoutes(
|
||||||
rest.WithMiddlewares(
|
rest.WithMiddlewares(
|
||||||
[]rest.Middleware{serverCtx.Authority},
|
[]rest.Middleware{serverCtx.Authority},
|
||||||
[]rest.Route{
|
[]rest.Route{
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/get/verifyCode",
|
Path: "/user",
|
||||||
Handler: user.GetVerifyCodeHandler(serverCtx),
|
Handler: user.GetUserInfoByIdHandler(serverCtx),
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/register",
|
|
||||||
Handler: user.RegisterHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/login",
|
|
||||||
Handler: user.LoginHandler(serverCtx),
|
|
||||||
},
|
},
|
||||||
}...,
|
}...,
|
||||||
),
|
),
|
||||||
//rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
|
||||||
|
"mingyang-admin-app-api/internal/logic/user"
|
||||||
|
"mingyang-admin-app-api/internal/svc"
|
||||||
|
"mingyang-admin-app-api/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// swagger:route post /user user GetUserInfoById
|
||||||
|
//
|
||||||
|
// Get userInfo detail by ID | 获取用户信息
|
||||||
|
//
|
||||||
|
// Get userInfo detail by ID | 获取用户信息
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: body
|
||||||
|
// require: true
|
||||||
|
// in: body
|
||||||
|
// type: IDReq
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: UserInfo
|
||||||
|
|
||||||
|
func GetUserInfoByIdHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.IDReq
|
||||||
|
if err := httpx.Parse(r, &req, true); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := user.NewGetUserInfoByIdLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetUserInfoById(&req)
|
||||||
|
if err != nil {
|
||||||
|
err = svcCtx.Trans.TransError(r.Context(), err)
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mingyang-admin-app-api/internal/logic/user"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
|
||||||
"mingyang-admin-app-api/internal/logic/user"
|
|
||||||
"mingyang-admin-app-api/internal/svc"
|
"mingyang-admin-app-api/internal/svc"
|
||||||
"mingyang-admin-app-api/internal/types"
|
"mingyang-admin-app-api/internal/types"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mingyang-admin-app-api/internal/logic/user"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
|
||||||
|
"mingyang-admin-app-api/internal/svc"
|
||||||
|
"mingyang-admin-app-api/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// swagger:route post /login user Login
|
||||||
|
//
|
||||||
|
// Login | 登录
|
||||||
|
//
|
||||||
|
// Login | 登录
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: body
|
||||||
|
// require: true
|
||||||
|
// in: body
|
||||||
|
// type: LoginReq
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: LoginResp
|
||||||
|
|
||||||
|
func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.LoginReq
|
||||||
|
if err := httpx.Parse(r, &req, true); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := user.NewLoginLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.Login(&req)
|
||||||
|
if err != nil {
|
||||||
|
err = svcCtx.Trans.TransError(r.Context(), err)
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mingyang-admin-app-api/internal/logic/user"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
|
||||||
"mingyang-admin-app-api/internal/logic/user"
|
|
||||||
"mingyang-admin-app-api/internal/svc"
|
"mingyang-admin-app-api/internal/svc"
|
||||||
"mingyang-admin-app-api/internal/types"
|
"mingyang-admin-app-api/internal/types"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"mingyang-admin-app-api/internal/svc"
|
||||||
|
"mingyang-admin-app-api/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetUserInfoByIdLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetUserInfoByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserInfoByIdLogic {
|
||||||
|
return &GetUserInfoByIdLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetUserInfoByIdLogic) GetUserInfoById(req *types.IDReq) (resp *types.UserInfo, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,170 @@
|
||||||
|
// internal/middleware/authority.go
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
|
"mingyang-admin-app-api/internal/types"
|
||||||
|
"mingyang-admin-app-rpc/appclient"
|
||||||
|
"mingyang-admin-app-rpc/types/app"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 定义上下文键类型
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserIDKey contextKey = "user_id"
|
||||||
|
UserInfoKey contextKey = "user_info"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthorityMiddleware struct {
|
type AuthorityMiddleware struct {
|
||||||
Rds redis.UniversalClient
|
Rds redis.UniversalClient
|
||||||
|
AppRpc appclient.App
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthorityMiddleware(rds redis.UniversalClient) *AuthorityMiddleware {
|
// NewAuthorityMiddleware 创建认证中间件
|
||||||
|
func NewAuthorityMiddleware(appRpc appclient.App, rds redis.UniversalClient) *AuthorityMiddleware {
|
||||||
return &AuthorityMiddleware{
|
return &AuthorityMiddleware{
|
||||||
Rds: rds,
|
AppRpc: appRpc,
|
||||||
|
Rds: rds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeResult 写入统一格式的响应
|
||||||
|
func writeResult(w http.ResponseWriter, statusCode int, result *types.BaseDataInfo) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(statusCode)
|
||||||
|
json.NewEncoder(w).Encode(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeError 写入错误响应(简化版)
|
||||||
|
func writeError(w http.ResponseWriter, statusCode int, message string) {
|
||||||
|
writeResult(w, statusCode, &types.BaseDataInfo{
|
||||||
|
Msg: message,
|
||||||
|
Code: 500,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 中间件处理函数
|
||||||
func (m *AuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
func (m *AuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
/* // get the path
|
startTime := time.Now()
|
||||||
obj := r.URL.Path
|
|
||||||
// get the method
|
// 检查是否为公开路径(可选)
|
||||||
act := r.Method
|
if m.isPublicPath(r.URL.Path) {
|
||||||
// get the role id
|
next(w, r)
|
||||||
roleIds := strings.Split(r.Context().Value("roleId").(string), ",")*/
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 从 Authorization Header 中提取 Bearer Token
|
||||||
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
if authHeader == "" {
|
||||||
|
writeError(w, 401, "Authorization header is required")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证 Bearer Token 格式
|
||||||
|
if !strings.HasPrefix(authHeader, "Bearer ") {
|
||||||
|
writeError(w, 401, "Invalid authorization format, must be 'Bearer <token>'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 提取 Token
|
||||||
|
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||||
|
if tokenString == "" {
|
||||||
|
writeError(w, 401, "Token cannot be empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查 Redis 缓存(可选)
|
||||||
|
if m.Rds != nil {
|
||||||
|
cacheKey := fmt.Sprintf("token:%s", tokenString)
|
||||||
|
cachedUserID, err := m.Rds.Get(r.Context(), cacheKey).Result()
|
||||||
|
if err == nil && cachedUserID != "" {
|
||||||
|
// 从缓存中获取到用户ID
|
||||||
|
ctx := context.WithValue(r.Context(), UserIDKey, cachedUserID)
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
next(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 调用 RPC 验证 Token
|
||||||
|
fmt.Printf("Validating token: %s\n", tokenString)
|
||||||
|
token, err := m.AppRpc.AuthToken(r.Context(), &app.AuthReq{Token: tokenString})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error validating token: %v\n", err)
|
||||||
|
// 根据错误类型返回不同的错误信息
|
||||||
|
var jwtErr *jwt.ValidationError
|
||||||
|
if errors.As(err, &jwtErr) {
|
||||||
|
switch {
|
||||||
|
case jwtErr.Errors&jwt.ValidationErrorExpired != 0:
|
||||||
|
writeError(w, 401, "Token has expired")
|
||||||
|
case jwtErr.Errors&jwt.ValidationErrorMalformed != 0:
|
||||||
|
writeError(w, 401, "Invalid token format")
|
||||||
|
case jwtErr.Errors&jwt.ValidationErrorSignatureInvalid != 0:
|
||||||
|
writeError(w, 401, "Invalid token signature")
|
||||||
|
case jwtErr.Errors&jwt.ValidationErrorNotValidYet != 0:
|
||||||
|
writeError(w, 401, "Token not valid yet")
|
||||||
|
default:
|
||||||
|
writeError(w, 401, "Invalid token")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 网络错误或其他错误
|
||||||
|
writeError(w, 500, "Token validation service unavailable")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 获取用户ID
|
||||||
|
id := token.UserId
|
||||||
|
|
||||||
|
// 7. 缓存到 Redis(可选)
|
||||||
|
if m.Rds != nil {
|
||||||
|
cacheKey := fmt.Sprintf("token:%s", tokenString)
|
||||||
|
// 设置缓存,过期时间30分钟
|
||||||
|
m.Rds.Set(r.Context(), cacheKey, id, 30*time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 设置到上下文
|
||||||
|
ctx := r.Context()
|
||||||
|
ctx = context.WithValue(ctx, UserIDKey, id)
|
||||||
|
ctx = context.WithValue(ctx, UserInfoKey, token)
|
||||||
|
|
||||||
|
// 9. 记录请求日志(可选)
|
||||||
|
fmt.Printf("[%s] %s - UserID: %d - Duration: %v\n",
|
||||||
|
time.Now().Format("2006-01-02 15:04:05"),
|
||||||
|
r.URL.Path,
|
||||||
|
id,
|
||||||
|
time.Since(startTime))
|
||||||
|
|
||||||
|
// 10. 继续处理请求
|
||||||
|
r = r.WithContext(ctx)
|
||||||
next(w, r)
|
next(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isPublicPath 检查是否为公开路径
|
||||||
|
func (m *AuthorityMiddleware) isPublicPath(path string) bool {
|
||||||
|
publicPaths := []string{
|
||||||
|
"/api/login",
|
||||||
|
"/api/register",
|
||||||
|
"/api/public/",
|
||||||
|
"/health",
|
||||||
|
"/metrics",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, publicPath := range publicPaths {
|
||||||
|
if strings.HasPrefix(path, publicPath) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package svc
|
package svc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
"github.com/saas-mingyang/mingyang-admin-common/i18n"
|
"github.com/saas-mingyang/mingyang-admin-common/i18n"
|
||||||
"github.com/zeromicro/go-zero/rest"
|
"github.com/zeromicro/go-zero/rest"
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
|
@ -15,15 +16,18 @@ type ServiceContext struct {
|
||||||
Trans *i18n.Translator
|
Trans *i18n.Translator
|
||||||
Authority rest.Middleware
|
Authority rest.Middleware
|
||||||
AppRpc appclient.App
|
AppRpc appclient.App
|
||||||
|
Redis redis.UniversalClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
trans := i18n.NewTranslator(c.I18nConf, i18n2.LocaleFS)
|
trans := i18n.NewTranslator(c.I18nConf, i18n2.LocaleFS)
|
||||||
|
appRpc := appclient.NewApp(zrpc.NewClientIfEnable(c.AppRpc))
|
||||||
rds := c.RedisConf.MustNewUniversalRedis()
|
rds := c.RedisConf.MustNewUniversalRedis()
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Authority: middleware.NewAuthorityMiddleware(rds).Handle,
|
Authority: middleware.NewAuthorityMiddleware(appRpc, rds).Handle,
|
||||||
Config: c,
|
Config: c,
|
||||||
|
Redis: rds,
|
||||||
Trans: trans,
|
Trans: trans,
|
||||||
AppRpc: appclient.NewApp(zrpc.NewClientIfEnable(c.AppRpc)),
|
AppRpc: appRpc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -362,3 +362,7 @@ type LoginResp struct {
|
||||||
AuthToken *AuthToken
|
AuthToken *AuthToken
|
||||||
UserInfo *UserInfo
|
UserInfo *UserInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swagger:model UserInfoReq
|
||||||
|
type UserInfoReq struct {
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,18 @@ enum VerifyCodeType {
|
||||||
CHANGE_PAY_PASSWORD = 8;
|
CHANGE_PAY_PASSWORD = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthInfoResp 是认证信息的响应
|
||||||
|
message AuthInfoResp {
|
||||||
|
uint64 user_id = 1;
|
||||||
|
string type = 2;
|
||||||
|
RegisteredClaims claims = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AuthReq {
|
||||||
|
string token = 1;
|
||||||
|
google.protobuf.Timestamp time = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// 认证令牌
|
// 认证令牌
|
||||||
message AuthToken {
|
message AuthToken {
|
||||||
string access_token = 1;
|
string access_token = 1;
|
||||||
|
|
@ -54,6 +66,11 @@ message BaseUUIDResp {
|
||||||
string msg = 2;
|
string msg = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClaimStrings 用于表示 JWT 中的 audience 字段
|
||||||
|
message ClaimStrings {
|
||||||
|
repeated string values = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// base message
|
// base message
|
||||||
message Empty {}
|
message Empty {}
|
||||||
|
|
||||||
|
|
@ -78,6 +95,11 @@ message LoginResponse {
|
||||||
AuthToken auth_token = 2;
|
AuthToken auth_token = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NumericDate 使用 timestamp 表示 JWT 中的时间字段
|
||||||
|
message NumericDate {
|
||||||
|
google.protobuf.Timestamp timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message PageInfoReq {
|
message PageInfoReq {
|
||||||
uint64 page = 1;
|
uint64 page = 1;
|
||||||
uint64 page_size = 2;
|
uint64 page_size = 2;
|
||||||
|
|
@ -118,6 +140,24 @@ message RegisterUserResponse {
|
||||||
bool phone_verification_required = 4;
|
bool phone_verification_required = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisteredClaims 是 JWT 声明集的结构化版本
|
||||||
|
message RegisteredClaims {
|
||||||
|
// iss (Issuer) - 签发者
|
||||||
|
string issuer = 1;
|
||||||
|
// sub (Subject) - 主题
|
||||||
|
string subject = 2;
|
||||||
|
// aud (Audience) - 受众
|
||||||
|
ClaimStrings audience = 3;
|
||||||
|
// exp (Expiration Time) - 过期时间
|
||||||
|
NumericDate expires_at = 4;
|
||||||
|
// nbf (Not Before) - 生效时间
|
||||||
|
NumericDate not_before = 5;
|
||||||
|
// iat (Issued At) - 签发时间
|
||||||
|
NumericDate issued_at = 6;
|
||||||
|
// jti (JWT ID) - JWT ID
|
||||||
|
string id = 7;
|
||||||
|
}
|
||||||
|
|
||||||
message UUIDReq {
|
message UUIDReq {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -162,6 +202,9 @@ message VerifyCodeResp {
|
||||||
|
|
||||||
// App 服务定义
|
// App 服务定义
|
||||||
service App {
|
service App {
|
||||||
|
// 校验token
|
||||||
|
// group: auth
|
||||||
|
rpc AuthToken(AuthReq) returns (AuthInfoResp);
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
// group: code
|
// group: code
|
||||||
rpc GetVerifyCode(VerifyCodeReq) returns (VerifyCodeResp);
|
rpc GetVerifyCode(VerifyCodeReq) returns (VerifyCodeResp);
|
||||||
|
|
|
||||||
|
|
@ -13,21 +13,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
AuthInfoResp = app.AuthInfoResp
|
||||||
|
AuthReq = app.AuthReq
|
||||||
AuthToken = app.AuthToken
|
AuthToken = app.AuthToken
|
||||||
BaseIDResp = app.BaseIDResp
|
BaseIDResp = app.BaseIDResp
|
||||||
BaseMsg = app.BaseMsg
|
BaseMsg = app.BaseMsg
|
||||||
BaseResp = app.BaseResp
|
BaseResp = app.BaseResp
|
||||||
BaseUUIDResp = app.BaseUUIDResp
|
BaseUUIDResp = app.BaseUUIDResp
|
||||||
|
ClaimStrings = app.ClaimStrings
|
||||||
Empty = app.Empty
|
Empty = app.Empty
|
||||||
IDReq = app.IDReq
|
IDReq = app.IDReq
|
||||||
IDsReq = app.IDsReq
|
IDsReq = app.IDsReq
|
||||||
LoginRequest = app.LoginRequest
|
LoginRequest = app.LoginRequest
|
||||||
LoginResponse = app.LoginResponse
|
LoginResponse = app.LoginResponse
|
||||||
|
NumericDate = app.NumericDate
|
||||||
PageInfoReq = app.PageInfoReq
|
PageInfoReq = app.PageInfoReq
|
||||||
PageUserRequest = app.PageUserRequest
|
PageUserRequest = app.PageUserRequest
|
||||||
PageUserResponse = app.PageUserResponse
|
PageUserResponse = app.PageUserResponse
|
||||||
RegisterUserRequest = app.RegisterUserRequest
|
RegisterUserRequest = app.RegisterUserRequest
|
||||||
RegisterUserResponse = app.RegisterUserResponse
|
RegisterUserResponse = app.RegisterUserResponse
|
||||||
|
RegisteredClaims = app.RegisteredClaims
|
||||||
UUIDReq = app.UUIDReq
|
UUIDReq = app.UUIDReq
|
||||||
UUIDsReq = app.UUIDsReq
|
UUIDsReq = app.UUIDsReq
|
||||||
UserInfo = app.UserInfo
|
UserInfo = app.UserInfo
|
||||||
|
|
@ -35,6 +40,8 @@ type (
|
||||||
VerifyCodeResp = app.VerifyCodeResp
|
VerifyCodeResp = app.VerifyCodeResp
|
||||||
|
|
||||||
App interface {
|
App interface {
|
||||||
|
// 校验token
|
||||||
|
AuthToken(ctx context.Context, in *AuthReq, opts ...grpc.CallOption) (*AuthInfoResp, error)
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error)
|
GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error)
|
||||||
// 用户注册
|
// 用户注册
|
||||||
|
|
@ -57,6 +64,12 @@ func NewApp(cli zrpc.Client) App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 校验token
|
||||||
|
func (m *defaultApp) AuthToken(ctx context.Context, in *AuthReq, opts ...grpc.CallOption) (*AuthInfoResp, error) {
|
||||||
|
client := app.NewAppClient(m.cli.Conn())
|
||||||
|
return client.AuthToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
func (m *defaultApp) GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error) {
|
func (m *defaultApp) GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error) {
|
||||||
client := app.NewAppClient(m.cli.Conn())
|
client := app.NewAppClient(m.cli.Conn())
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
|
||||||
|
package app;
|
||||||
|
option go_package = "./app";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
|
||||||
|
// ClaimStrings 用于表示 JWT 中的 audience 字段
|
||||||
|
message ClaimStrings {
|
||||||
|
repeated string values = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NumericDate 使用 timestamp 表示 JWT 中的时间字段
|
||||||
|
message NumericDate {
|
||||||
|
google.protobuf.Timestamp timestamp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisteredClaims 是 JWT 声明集的结构化版本
|
||||||
|
message RegisteredClaims {
|
||||||
|
// iss (Issuer) - 签发者
|
||||||
|
string issuer = 1;
|
||||||
|
|
||||||
|
// sub (Subject) - 主题
|
||||||
|
string subject = 2;
|
||||||
|
|
||||||
|
// aud (Audience) - 受众
|
||||||
|
ClaimStrings audience = 3;
|
||||||
|
|
||||||
|
// exp (Expiration Time) - 过期时间
|
||||||
|
NumericDate expires_at = 4;
|
||||||
|
|
||||||
|
// nbf (Not Before) - 生效时间
|
||||||
|
NumericDate not_before = 5;
|
||||||
|
|
||||||
|
// iat (Issued At) - 签发时间
|
||||||
|
NumericDate issued_at = 6;
|
||||||
|
|
||||||
|
// jti (JWT ID) - JWT ID
|
||||||
|
string id = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthInfoResp 是认证信息的响应
|
||||||
|
message AuthInfoResp {
|
||||||
|
uint64 user_id = 1;
|
||||||
|
string type = 2;
|
||||||
|
RegisteredClaims claims = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AuthReq {
|
||||||
|
string token = 1;
|
||||||
|
google.protobuf.Timestamp time = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// App 服务定义
|
||||||
|
service App {
|
||||||
|
// 校验token
|
||||||
|
// group: auth
|
||||||
|
rpc AuthToken(AuthReq) returns (AuthInfoResp);
|
||||||
|
}
|
||||||
|
|
@ -21,10 +21,10 @@ RedisConf:
|
||||||
Db: 0
|
Db: 0
|
||||||
|
|
||||||
JWTConf:
|
JWTConf:
|
||||||
access_token_secret: OAMDAascvzcvasdf
|
access_token_secret: KdAj3ZnmHpVvGKBthWXmTNPRcdZaWP7cnbsvmJSYRadN8PebaaAQENVKDD6WCm
|
||||||
refresh_token_secret: ASDZCpajbvasdfasf
|
refresh_token_secret: J8WRjFcuGpeAnymn5GNvbTJKn2uQsXdjvCFT4dK4dY5TtH88SNwzGH7btJ6ck
|
||||||
access_token_expiry: 24h
|
access_token_expiry: 30m
|
||||||
refresh_token_expiry: 720h
|
refresh_token_expiry: 24h
|
||||||
issuer: user-system
|
issuer: user-system
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
"mingyang-admin-app-rpc/internal/jwt_manager"
|
||||||
|
|
||||||
|
"mingyang-admin-app-rpc/internal/svc"
|
||||||
|
"mingyang-admin-app-rpc/types/app"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TokenLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
jwtManager *jwt_manager.JWTManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAuthTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TokenLogic {
|
||||||
|
return &TokenLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
jwtManager: jwt_manager.NewJWTManager(&svcCtx.Config.JWTConf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthToken 校验token
|
||||||
|
func (l *TokenLogic) AuthToken(in *app.AuthReq) (*app.AuthInfoResp, error) {
|
||||||
|
token, err := l.jwtManager.VerifyAccessToken(in.GetToken())
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("verify access token failed: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &app.AuthInfoResp{
|
||||||
|
UserId: token.UserID,
|
||||||
|
Type: token.Type,
|
||||||
|
Claims: &app.RegisteredClaims{
|
||||||
|
IssuedAt: &app.NumericDate{
|
||||||
|
Timestamp: ×tamppb.Timestamp{
|
||||||
|
Seconds: token.IssuedAt.Unix(), // 转换为 Unix 时间戳
|
||||||
|
Nanos: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpiresAt: &app.NumericDate{
|
||||||
|
Timestamp: ×tamppb.Timestamp{
|
||||||
|
Seconds: token.ExpiresAt.Unix(), // 转换为 Unix 时间戳
|
||||||
|
Nanos: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Issuer: token.Issuer,
|
||||||
|
Subject: token.Subject,
|
||||||
|
Audience: &app.ClaimStrings{
|
||||||
|
Values: token.Audience,
|
||||||
|
},
|
||||||
|
NotBefore: &app.NumericDate{
|
||||||
|
Timestamp: ×tamppb.Timestamp{
|
||||||
|
Seconds: token.NotBefore.Unix(), // 转换为 Unix 时间戳
|
||||||
|
Nanos: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Id: token.ID,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ package server
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"mingyang-admin-app-rpc/internal/logic/auth"
|
||||||
"mingyang-admin-app-rpc/internal/logic/base"
|
"mingyang-admin-app-rpc/internal/logic/base"
|
||||||
"mingyang-admin-app-rpc/internal/logic/code"
|
"mingyang-admin-app-rpc/internal/logic/code"
|
||||||
"mingyang-admin-app-rpc/internal/logic/user"
|
"mingyang-admin-app-rpc/internal/logic/user"
|
||||||
|
|
@ -24,6 +25,12 @@ func NewAppServer(svcCtx *svc.ServiceContext) *AppServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 校验token
|
||||||
|
func (s *AppServer) AuthToken(ctx context.Context, in *app.AuthReq) (*app.AuthInfoResp, error) {
|
||||||
|
l := auth.NewAuthTokenLogic(ctx, s.svcCtx)
|
||||||
|
return l.AuthToken(in)
|
||||||
|
}
|
||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
func (s *AppServer) GetVerifyCode(ctx context.Context, in *app.VerifyCodeReq) (*app.VerifyCodeResp, error) {
|
func (s *AppServer) GetVerifyCode(ctx context.Context, in *app.VerifyCodeReq) (*app.VerifyCodeResp, error) {
|
||||||
l := code.NewGetVerifyCodeLogic(ctx, s.svcCtx)
|
l := code.NewGetVerifyCodeLogic(ctx, s.svcCtx)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -19,6 +19,7 @@ import (
|
||||||
const _ = grpc.SupportPackageIsVersion9
|
const _ = grpc.SupportPackageIsVersion9
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
App_AuthToken_FullMethodName = "/app.App/AuthToken"
|
||||||
App_GetVerifyCode_FullMethodName = "/app.App/GetVerifyCode"
|
App_GetVerifyCode_FullMethodName = "/app.App/GetVerifyCode"
|
||||||
App_RegisterUser_FullMethodName = "/app.App/RegisterUser"
|
App_RegisterUser_FullMethodName = "/app.App/RegisterUser"
|
||||||
App_LoginUser_FullMethodName = "/app.App/LoginUser"
|
App_LoginUser_FullMethodName = "/app.App/LoginUser"
|
||||||
|
|
@ -32,6 +33,9 @@ const (
|
||||||
//
|
//
|
||||||
// App 服务定义
|
// App 服务定义
|
||||||
type AppClient interface {
|
type AppClient interface {
|
||||||
|
// 校验token
|
||||||
|
// group: auth
|
||||||
|
AuthToken(ctx context.Context, in *AuthReq, opts ...grpc.CallOption) (*AuthInfoResp, error)
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
// group: code
|
// group: code
|
||||||
GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error)
|
GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error)
|
||||||
|
|
@ -56,6 +60,16 @@ func NewAppClient(cc grpc.ClientConnInterface) AppClient {
|
||||||
return &appClient{cc}
|
return &appClient{cc}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *appClient) AuthToken(ctx context.Context, in *AuthReq, opts ...grpc.CallOption) (*AuthInfoResp, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(AuthInfoResp)
|
||||||
|
err := c.cc.Invoke(ctx, App_AuthToken_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *appClient) GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error) {
|
func (c *appClient) GetVerifyCode(ctx context.Context, in *VerifyCodeReq, opts ...grpc.CallOption) (*VerifyCodeResp, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
out := new(VerifyCodeResp)
|
out := new(VerifyCodeResp)
|
||||||
|
|
@ -112,6 +126,9 @@ func (c *appClient) InitDatabase(ctx context.Context, in *Empty, opts ...grpc.Ca
|
||||||
//
|
//
|
||||||
// App 服务定义
|
// App 服务定义
|
||||||
type AppServer interface {
|
type AppServer interface {
|
||||||
|
// 校验token
|
||||||
|
// group: auth
|
||||||
|
AuthToken(context.Context, *AuthReq) (*AuthInfoResp, error)
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
// group: code
|
// group: code
|
||||||
GetVerifyCode(context.Context, *VerifyCodeReq) (*VerifyCodeResp, error)
|
GetVerifyCode(context.Context, *VerifyCodeReq) (*VerifyCodeResp, error)
|
||||||
|
|
@ -136,6 +153,9 @@ type AppServer interface {
|
||||||
// pointer dereference when methods are called.
|
// pointer dereference when methods are called.
|
||||||
type UnimplementedAppServer struct{}
|
type UnimplementedAppServer struct{}
|
||||||
|
|
||||||
|
func (UnimplementedAppServer) AuthToken(context.Context, *AuthReq) (*AuthInfoResp, error) {
|
||||||
|
return nil, status.Error(codes.Unimplemented, "method AuthToken not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedAppServer) GetVerifyCode(context.Context, *VerifyCodeReq) (*VerifyCodeResp, error) {
|
func (UnimplementedAppServer) GetVerifyCode(context.Context, *VerifyCodeReq) (*VerifyCodeResp, error) {
|
||||||
return nil, status.Error(codes.Unimplemented, "method GetVerifyCode not implemented")
|
return nil, status.Error(codes.Unimplemented, "method GetVerifyCode not implemented")
|
||||||
}
|
}
|
||||||
|
|
@ -172,6 +192,24 @@ func RegisterAppServer(s grpc.ServiceRegistrar, srv AppServer) {
|
||||||
s.RegisterService(&App_ServiceDesc, srv)
|
s.RegisterService(&App_ServiceDesc, srv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _App_AuthToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(AuthReq)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AppServer).AuthToken(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: App_AuthToken_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AppServer).AuthToken(ctx, req.(*AuthReq))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _App_GetVerifyCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _App_GetVerifyCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(VerifyCodeReq)
|
in := new(VerifyCodeReq)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
|
|
@ -269,6 +307,10 @@ var App_ServiceDesc = grpc.ServiceDesc{
|
||||||
ServiceName: "app.App",
|
ServiceName: "app.App",
|
||||||
HandlerType: (*AppServer)(nil),
|
HandlerType: (*AppServer)(nil),
|
||||||
Methods: []grpc.MethodDesc{
|
Methods: []grpc.MethodDesc{
|
||||||
|
{
|
||||||
|
MethodName: "AuthToken",
|
||||||
|
Handler: _App_AuthToken_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "GetVerifyCode",
|
MethodName: "GetVerifyCode",
|
||||||
Handler: _App_GetVerifyCode_Handler,
|
Handler: _App_GetVerifyCode_Handler,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue