fusenapi/utils/basic/request_parse.go
2023-08-28 12:23:12 +08:00

188 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package basic
import (
"errors"
"fmt"
"log"
"strconv"
"fusenapi/shared"
"fusenapi/utils/auth"
"net/http"
"reflect"
"github.com/golang-jwt/jwt"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"gorm.io/gorm"
)
type IJWTParse interface {
ParseJwtToken(r *http.Request) (jwt.MapClaims, error)
}
func BeforeLogic(w http.ResponseWriter, r *http.Request, l reflect.Value) (isNext bool) {
m := l.MethodByName("BeforeLogic")
if m.IsValid() {
result := m.Call([]reflect.Value{reflect.ValueOf(w), reflect.ValueOf(r)})
if len(result) != 0 {
return false
}
}
return true
}
func AfterLogic(w http.ResponseWriter, r *http.Request, l reflect.Value, resp *Response) bool {
m := l.MethodByName("AfterLogic")
if m.IsValid() {
m.Call([]reflect.Value{reflect.ValueOf(w), reflect.ValueOf(r), reflect.ValueOf(resp)})
return true
}
return false
}
func NormalAfterLogic(w http.ResponseWriter, r *http.Request, resp *Response) {
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {
err := errors.New("server logic is error, resp must not be nil")
httpx.ErrorCtx(r.Context(), w, err)
logx.Error(err)
}
}
func ParseJwtToken(r *http.Request, svcCtx any) (*auth.UserInfo, error) {
var userinfo *auth.UserInfo
var err error
// log.Println(io.ReadAll(r.Body))
token := r.Header.Get("Authorization")
userId, err := strconv.ParseInt(token, 10, 64)
if err == nil {
userinfo = &auth.UserInfo{
UserId: userId,
}
} else {
var secret uint64 = 0
token, info, err := auth.ParseJwtTokenHeader[auth.UserInfo](r) //解析Token头, 和payload信息
if err != nil {
logx.Error(err)
return nil, err
}
if info != nil {
if info.IsUser() {
// us, err := state.GetUserState(info.UserId) //获取缓存的用户状态
reflect.ValueOf(svcCtx)
ctxValue := reflect.ValueOf(svcCtx).FieldByName("MysqlConn")
gdb := ctxValue.Interface().(*gorm.DB)
us, err := shared.GetUserState(info.UserId, gdb)
if err != nil {
logx.Error(err)
return nil, err
}
secret = us.PwdHash // 获取密码的hash做jwt, 便于重置密码的使用
} else if info.IsGuest() {
secret = auth.DefaultJwtSecret //获取默认的hash
}
}
if secret != 0 {
log.Println("secret != 0", info)
claims, err := auth.ParseJwtTokenUint64Secret(token, secret)
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
log.Println(token)
if err != nil {
return nil, fmt.Errorf("unauthorized")
}
return nil, err
}
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
return nil, fmt.Errorf("unauthorized")
}
}
} else {
// 白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
}
return userinfo, nil
}
func RequestParse(w http.ResponseWriter, r *http.Request, svcCtx any, LogicRequest any) (*auth.UserInfo, error) {
// 新的解析jwtToken
userinfo, err := ParseJwtToken(r, svcCtx)
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &Response{
Code: 510,
Message: err.Error(),
})
}
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err = httpx.Parse(r, LogicRequest); err != nil {
httpx.OkJsonCtx(r.Context(), w, &Response{
Code: 510,
Message: "parameter error",
})
logx.Error(err)
return nil, err
}
// userinfo := &auth.UserInfo{UserId: 39}
return userinfo, err
}
func RequestParseBackend(w http.ResponseWriter, r *http.Request, svcCtx IJWTParse, LogicRequest any) (userinfo *auth.BackendUserInfo, err error) {
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &Response{
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetBackendUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
}
// var req types.RequestGoogleLogin
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err = httpx.Parse(r, LogicRequest); err != nil {
httpx.OkJsonCtx(r.Context(), w, &Response{
Code: 510,
Message: "parameter error",
})
logx.Info(err)
return
}
return userinfo, err
}