go-zero教程——User rpc - Userinfo

2,562 阅读3分钟

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.gouserinfologic.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"}}%
➜  ~

注意 鉴权参数 Authorizationlogin 接口返回的 token

这样,用户管理rpc - Userinfo就开发完成了。

上一篇《go-zero教程——User rpc - Register》

下一篇《go-zero教程——Food API Gateway》