Skip to content

使用中间件实现jwt功能,没什么难的地方,只是试一下中间件怎么使用,注意,在编写api文件时,中间件的首字母需要大写

api

api
syntax = "v1"
type loginReq {
	Email    string `form:"email"`
	Password string `form:"password"`
}

type loginResp {
	Data string `json:"data"`
}

type getInformResp {
	Inform string `json:"inform"`
}

service middleware {
	@handler loginHandler
	post /user/login (loginReq) returns (loginResp)
}

@server(
	middleware: LoginMiddleWare
)
service middleware {
	@handler getInform
	post /user/getInform returns (getInformResp)
}

logic

middleWareLogic

go
package middleware

import (
	"context"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
)

var secret = []byte("123123123")

type Claims struct {
	jwt.RegisteredClaims
	Email string `json:"email"`
	Uid   string `json:"uid"`
}

type LoginMiddleWareMiddleware struct {
}

func NewLoginMiddleWareMiddleware() *LoginMiddleWareMiddleware {
	return &LoginMiddleWareMiddleware{}
}

func parseJwt(jwtString string) (*jwt.Token, *Claims, error) {
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(jwtString, claims, func(token *jwt.Token) (interface{}, error) {
		return secret, nil
	})
	return token, claims, err
}

func (m *LoginMiddleWareMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		get := r.Header.Get("Authorization")
		if get == "" {
			http.Error(w, "未认证", http.StatusUnauthorized)
		}
		token, claims, err := parseJwt(get)
		if err != nil && !token.Valid {
			http.Error(w, "认证信息错误", http.StatusUnauthorized)
		}
		context1 := context.WithValue(context.Background(), "uid", claims.Uid)
		value := context.WithValue(context1, "email", claims.Email)
		r2 := r.WithContext(value)
		next(w, r2)
	}
}

loginLogic

go
package logic

import (
	"context"
	"github.com/golang-jwt/jwt/v5"
	"time"

	"example.com/strconv/go-zero-middleware/internal/svc"
	"example.com/strconv/go-zero-middleware/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

var secret = []byte("123123123")

type LoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}
type Claims struct {
	jwt.RegisteredClaims
	Email string `json:"email"`
	Uid   string `json:"uid"`
}

func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
	return &LoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}
func getJwt(uid, email string) (string, error) {
	duration := time.Minute * 50
	now := time.Now()
	claims := &Claims{
		Email: email,
		Uid:   uid,
		RegisteredClaims: jwt.RegisteredClaims{
			NotBefore: jwt.NewNumericDate(now),
			IssuedAt:  jwt.NewNumericDate(now),
			ExpiresAt: jwt.NewNumericDate(now.Add(duration)),
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedString, err := token.SignedString(secret)
	if err != nil {
		return "", err
	}
	return signedString, nil
}
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
	s, err := getJwt("1", req.Email)
	if err != nil {
		return
	}
	resp = new(types.LoginResp)
	resp.Data = s
	return
}

getInformLogic

go
package logic

import (
	"context"

	"example.com/strconv/go-zero-middleware/internal/svc"
	"example.com/strconv/go-zero-middleware/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetInformLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetInformLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetInformLogic {
	return &GetInformLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetInformLogic) GetInform() (resp *types.GetInformResp, err error) {
	s := l.ctx.Value("uid").(string)
	email := l.ctx.Value("email").(string)
	resp = new(types.GetInformResp)
	resp.Inform = s + email
	return
}