# 中间件使用 # 概要 jwt携带用户id信息 jwt 用户信息与header用户信息校验 # 修改jwt token生成逻辑 编辑loginlogic.go,将getJwtToken方法中添加`userId`参数,并将其添加到jwt token生成逻辑中,变更内容如下 getJwtToken方法 ```golang func (l *LoginLogic) getJwtToken(secretKey string, iat, seconds, userId int64) (string, error) { ... claims["userId"] = userId ... } ``` Login方法 ```golang func (l *LoginLogic) Login(req types.LoginReq) (*types.UserReply, error) { ... jwtToken, err := l.getJwtToken(l.svcCtx.Config.Auth.AccessSecret, now, accessExpire, userInfo.Id) ... } ``` # 添加中间件 添加middleware文件夹,并新建usercheckmiddleware.go ```bash $ cd book/user/api/internal $ mkdir middleware && cd middleware $ touch usercheckmiddleware.go ``` # 修改user.api文件 在`/user/info`路由所在service上添加`middleware`标识,然后重新生成代码 ```bash ... @server( jwt: Auth middleware: UserCheck ) service user-api { @handler userInfo get /user/info () returns (UserReply) } ``` # 填充ServiceContext ```bash $ vi ~/book/user/api/internal/svc/servicecontext.go ``` ```go package svc import ( "book/user/api/internal/config" "book/user/api/internal/middleware" "book/user/model" "github.com/tal-tech/go-zero/core/stores/sqlx" "github.com/tal-tech/go-zero/rest" ) type ServiceContext struct { Config config.Config UserModel model.UserModel UserCheck rest.Middleware } func NewServiceContext(c config.Config) *ServiceContext { conn := sqlx.NewMysql(c.Mysql.DataSource) um := model.NewUserModel(conn) return &ServiceContext{ Config: c, UserModel: um, UserCheck: middleware.NewUserCheckMiddleware().Handle, } } ``` # 填充中间件逻辑 usercheckmiddleware.go ```go package middleware import ( "encoding/json" "errors" "fmt" "net/http" "github.com/tal-tech/go-zero/rest/httpx" ) var ( errorUserInfo = errors.New("用户信息获取失败") authDeny = errors.New("用户信息不一致") ) const userKey = `x-user-id` type UserCheckMiddleware struct { } func NewUserCheckMiddleware() *UserCheckMiddleware { return &UserCheckMiddleware{} } func (m *UserCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userId := r.Header.Get(userKey) jwtUserId := r.Context().Value("userId") userInt, err := json.Number(userId).Int64() if err != nil { httpx.Error(w, errorUserInfo) return } jwtInt, err := json.Number(fmt.Sprintf("%v", jwtUserId)).Int64() if err != nil { httpx.Error(w, errorUserInfo) return } if jwtInt != userInt { httpx.Error(w, authDeny) return } next(w, r) } } ``` # 验证 ```bash $ curl -X GET \ http://127.0.0.1:8888/user/info \ -H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDM2NDA5NTMsImlhdCI6MTYwMzU1NDU1MywidXNlcklkIjoxfQ.clyoXd7_5AJLJ_y41Wc8g9nmzvmO2qPYu_JIODK_RAQ' \ -H 'x-user-id: 2' ``` ![user-auth-failed.png](https://cdn.nlark.com/yuque/0/2020/png/465993/1603555726300-90bdb881-ccfc-4b05-8ff5-c83e61b572e4.png#align=left&display=inline&height=616&margin=%5Bobject%20Object%5D&name=user-auth-failed.png&originHeight=616&originWidth=2224&size=137447&status=done&style=none&width=2224)