API Gateway
增加 Jwt
鉴权
userinfo
接口与 login register
接口不同,在接口调用的时候,需要做鉴权。
编辑 api/etc
下的 user-api.yaml
文件,新增如下
Auth:
AccessSecret: ad879037-d3fd-tghj-112d-6bfc35d54b7d
AccessExpire: 86400
注意 这里的 AccessSecret
需要与之前 rpc
中的 AccessSecret
保持一致。
编辑 api/internal/config
下的 config.go
文件,新增如下
type Config struct {
rest.RestConf
User zrpc.RpcClientConf
Auth struct {
AccessSecret string
AccessExpire int64
}
}
编辑 api
下的 user.api
文件, 修改为如下
info(
title: // UserApi
desc: // 用户服务相关API
)
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
}
type LoginResponse struct {
UserReply
}
type RegisterRequest struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
}
type RegisterResponse struct {
UserReply
}
type UserinfoResponse struct {
UserReply
}
type UserReply {
Id int64 `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
JwtToken
}
type JwtToken {
AccessToken string `json:"accessToken,omitempty"`
AccessExpire int64 `json:"accessExpire,omitempty"`
RefreshAfter int64 `json:"refreshAfter,omitempty"`
}
service user-api {
@handler Login // 用户登录
post /users/login(LoginRequest) returns(LoginResponse)
@handler Register // 用户注册
post /users/register(RegisterRequest) returns(RegisterResponse)
}
@server(
jwt: Auth
)
service user-api {
@handler UserInfo // 用户信息
post /users/userinfo() returns(UserinfoResponse)
}
UserInfo
接口的调用需要 jwt
鉴权,于是,我们新增了
@server(
jwt: Auth
)
service user-api {
@handler UserInfo // 用户信息
post /users/userinfo() returns(UserinfoResponse)
}
由于原来我们生成过 user-api
服务,userinfohandle.go
和 userinfologic.go
文件不符合我们现在的需求,需要删除掉重新生成新文件。
重新生成user-api
服务
goctl api go -api user.api -dir .
查看 api/internal/handler
下的 routers.go
文件。 userinfo
接口与 login register
接口分开处理了,并且增加了 rest.WithJwt(serverCtx.Config.Auth.AccessSecret)
鉴权处理。
func RegisterHandlers(engine *rest.Server, serverCtx *svc.ServiceContext) {
engine.AddRoutes(
[]rest.Route{
{
Method: http.MethodPost,
Path: "/users/login",
Handler: LoginHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/users/register",
Handler: RegisterHandler(serverCtx),
},
},
)
engine.AddRoutes(
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.Usercheck.Handle},
[]rest.Route{
{
Method: http.MethodPost,
Path: "/users/userinfo",
Handler: UserInfoHandler(serverCtx),
},
}...,
),
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
)
}
API Gateway 代码调用 user rpc 服务
编辑 api/internal/handler
下的 userinfohandler.go
文件,新增如下代码
func UserInfoHandler(ctx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
userId:=r.Header.Get("x-user-id")
l := logic.NewUserInfoLogic(r.Context(), ctx)
resp, err := l.UserInfo(userId)
if err != nil {
httpx.OkJson(w, ningxi.FailureResponse(nil,err.Error(),1000))
} else {
httpx.OkJson(w, ningxi.SuccessResponse(resp,"获取成功"))
}
}
}
编辑 api/internal/logic
下的 userinfologic.go
文件,新增如下代码
func (l *UserInfoLogic) UserInfo(userid string) (*types.UserinfoResponse, error) {
resp,err := l.svcCtx.User.Userinfo(l.ctx,&user.UserinfoRequest{
Userid: userid,
})
if err != nil {
return nil, err
}
response := types.UserReply{
Id: resp.Id,
Email: resp.Email,
}
return &types.UserinfoResponse{
response,
},nil
}
注意 UserInfo
方法 原本是不带参数的,这里新增了 userid
参数。
rpc 代码调用 crud+cache 代码
编辑 rpc/user/internal/logic
下的 userinfologic.go
文件,新增如下代码
func (l *UserinfoLogic) Userinfo(in *user.UserinfoRequest) (*user.Response, error) {
newid,_ := strconv.ParseInt(in.Userid,10,64)
result, err := l.svcCtx.Model.FindOne(newid)
if err == nil {
return &user.Response{
Id: result.Id,
Email: result.Email,
}, nil
} else {
return nil,err
}
}
启动服务
启动服务,注意 在启动服务前,需要确保 先前文章用到的 ningxi-compose
正常运行起来。
启动 user rpc
服务, 运行成功后,user rpc
则运行在本机的 8080
端口
➜ FoodGuides git:(master) ✗ go run usermanage/rpc/user/user.go -f usermanage/rpc/user/etc/user.yaml
Starting rpc server at 127.0.0.1:8080...
启动 user api
服务, 运行成功后,user api
则运行在本机的 8888
端口
➜ FoodGuides git:(master) ✗ go run usermanage/api/user.go -f usermanage/api/etc/user-api.yaml
Starting server at 0.0.0.0:8888...
api
测试
不带 Authorization
➜ ~ curl -i -X POST \
http://127.0.0.1:8888/users/userinfo \
-H 'cache-control: no-cache'
HTTP/1.1 401 Unauthorized
Date: Mon, 25 Jan 2021 03:39:56 GMT
Content-Length: 0
➜ ~
带 Authorization x-user-id
➜ ~ curl -i -X POST \
http://127.0.0.1:8888/users/userinfo \
-H 'authorization:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTE1NTM5MjAsImlhdCI6MTYxMTQ2NzUyMCwidXNlcklkIjozfQ.exhP3C79W35OlSHL4JFsCgpWdebtuCQzxJGsYQWI3xo' \
-H 'x-user-id:1'
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 25 Jan 2021 04:17:12 GMT
Content-Length: 95
{"code":1,"message":"获取成功","result":{"id":1,"username":"","email":"ningxi@ningxi.com"}}%
➜ ~
注意 鉴权参数 Authorization
为 login
接口返回的 token
这样,用户管理rpc - Userinfo
就开发完成了。