快速开始api开发(四)登录与认证
本文需要介绍 gotools 工具
需要使用的工具命令:
gotools handler -h
代码地址:github.com/wuyan94zl/gotools
登录
生成
执行:gotools handler --dir users --method POST --name login
路由 POST /users/login
设置登录出入参
修改:app/types/users.go
type UsersLoginRequest struct {
LoginID string `json:"login_id" validate:"required,gte=6,lte=32" tip:"用户登录名长度介于6-32位"`
Password string `json:"password" validate:"required,gte=6,lte=32" tip:"用户密码长度介于6-32位"`
}
type UsersLoginResponse struct {
ExpTime interface{} `json:"exp_time"` // 增加代码
Token interface{} `json:"token"` // 增加代码
}
编写登录逻辑
修改:app/logic/users/login.go
package users
import (
"errors"
"github.com/gin-gonic/gin"
"github.com/wuyan94zl/example-api/container"
"github.com/wuyan94zl/example-api/app/types"
"github.com/wuyan94zl/gotools/jwt"
"github.com/wuyan94zl/gotools/utils"
)
func LoginLogic(c *gin.Context, req *types.UsersLoginRequest) (*types.UsersLoginResponse, error) {
info, err := container.Instance().UserModel.FindByLoginID(c.Copy(), req.LoginID)
if err != nil {
return nil, errors.New("用户不存在")
}
if info.Password != utils.Md5ByString(req.Password+info.LoginID) {
return nil, errors.New("密码错误")
}
data := make(map[string]interface{})
data["ID"] = info.ID
data["Nickname"] = info.Nickname
token, err := jwt.GenToken(container.Instance().Jwt, data)
if err != nil {
return nil, err
}
return &types.UsersLoginResponse{
ExpTime: token["expTime"],
Token: token["token"],
}, nil
}
认证
生成
执行 gotools handler --dir auth --method GET --name info
路由 GET /auth/info
认证中间件
创建:app/middleware/auth.go
package middleware
import (
"github.com/gin-gonic/gin"
"github.com/wuyan94zl/example-api/container"
"github.com/wuyan94zl/gotools/jwt"
)
func ApiAuth() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.Request.Header.Get("Authorization")
token, err := jwt.AuthBearerToken(container.Instance().Jwt, tokenString)
if err != nil {
c.JSON(401, err)
c.Abort()
}
data := token["Data"].(map[string]interface{})
for k, v := range data {
c.Set(k, v)
}
// 保存用户到 上下文
c.Next()
}
}
路由
修改 router/route.go
package router
import (
"github.com/gin-gonic/gin"
"github.com/wuyan94zl/example-api/app/middleware"
)
func RegisterHandlers(app *gin.RouterGroup) {
registerUsersHandler(app)
authApp := app.Group("", middleware.ApiAuth()) // 增加认证路由组
registerAuthHandler(authApp)// 修改传参
}
入参出参设置
package types
type AuthInfoRequest struct{}
type AuthInfoResponse struct {
ID int `json:"id"`
Nickname string `json:"nickname"`
HeadImg string `json:"head_img"`
}
逻辑编写
package auth
import (
"github.com/gin-gonic/gin"
"github.com/wuyan94zl/example-api/container"
"github.com/wuyan94zl/example-api/app/types"
)
func InfoLogic(c *gin.Context, req *types.AuthInfoRequest) (*types.AuthInfoResponse, error) {
id := c.MustGet("ID").(float64)
info, err := container.Instance().UserModel.First(c.Copy(), int64(id))
if err != nil {
return nil, err
}
return &types.AuthInfoResponse{
ID: info.ID,
Nickname: info.Nickname,
HeadImg: info.HeadImg,
}, nil
}
结束
下节 定时任务 crontab 和 队列 queue (划重点)
本作品采用《CC 协议》,转载必须注明作者和本文链接