jwt 认证

This commit is contained in:
eson 2023-06-06 20:08:32 +08:00
parent ab9df9bc42
commit 48be41f64b
11 changed files with 192 additions and 44 deletions

4
.gitignore vendored
View File

@ -28,4 +28,6 @@
.history/ .history/
# Built Visual Studio Code Extensions # Built Visual Studio Code Extensions
*.vsix *.vsix
__debug_bin

View File

@ -52,4 +52,54 @@ func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string,
if len(data) == 1 { if len(data) == 1 {
resp.Data = data[0] resp.Data = data[0]
} }
}
// Set 设置Response的Code和Message值
func (resp *ResponseJwt) Set(Code int, Message string) {
resp.Code = Code
resp.Message = Message
}
// Set 设置整个Response
func (resp *ResponseJwt) SetWithData(Code int, Message string, Data interface{}) {
resp.Code = Code
resp.Message = Message
resp.Data = Data
}
// SetMessage 设置Response的Message
func (resp *ResponseJwt) SetMessage(msg string) {
resp.Message = msg
}
// SetWithData 设置Data
func (resp *ResponseJwt) SetData(Data interface{}) {
resp.Data = Data
}
// SetWithData 设置Response的Code和Message值 带Data入参数
func (resp *ResponseJwt) SetCode(Code int) {
resp.Code = Code
}
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
func (resp *ResponseJwt) SetStatus(sr *basic.StatusResponse, data ...interface{}) {
resp.Code = sr.Code
resp.Message = sr.Message
if len(data) == 1 {
resp.Data = data[0]
}
}
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
func (resp *ResponseJwt) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) {
resp.Code = sr.Code
resp.Message = msg
if len(data) == 1 {
resp.Data = data[0]
}
} }

View File

@ -6,3 +6,4 @@ SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth: Auth:
AccessSecret: fusen2023 AccessSecret: fusen2023
AccessExpire: 60 AccessExpire: 60
RefreshAfter: 60

View File

@ -35,8 +35,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
}, },
) )
server.AddRoutes( server.AddRoutes(
[]rest.Route{ []rest.Route{
{ {
@ -46,6 +44,5 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
}, },
}, },
rest.WithJwt(serverCtx.Config.Auth.AccessSecret), rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
) )
} }

View File

@ -2,6 +2,7 @@ package handler
import ( import (
"errors" "errors"
"fmt"
"net/http" "net/http"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
@ -10,6 +11,7 @@ import (
"fusenapi/home-user-auth/internal/logic" "fusenapi/home-user-auth/internal/logic"
"fusenapi/home-user-auth/internal/svc" "fusenapi/home-user-auth/internal/svc"
"fusenapi/home-user-auth/internal/types" "fusenapi/home-user-auth/internal/types"
"fusenapi/utils/basic"
) )
func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
@ -25,7 +27,10 @@ func UserLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
} }
l := logic.NewUserLoginLogic(r.Context(), svcCtx) l := logic.NewUserLoginLogic(r.Context(), svcCtx)
resp := l.UserLogin(&req) resp, token := l.UserLogin(&req)
if resp.Code == basic.CodeOK.Code {
w.Header().Add("Authorization", fmt.Sprintf("Bearer %s", token))
}
if resp != nil { if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp) httpx.OkJsonCtx(r.Context(), w, resp)
} else { } else {

View File

@ -2,6 +2,7 @@ package logic
import ( import (
"context" "context"
"log"
"fusenapi/home-user-auth/internal/svc" "fusenapi/home-user-auth/internal/svc"
"fusenapi/home-user-auth/internal/types" "fusenapi/home-user-auth/internal/types"
@ -29,6 +30,9 @@ func NewUserBasicInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Use
func (l *UserBasicInfoLogic) UserBasicInfo(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) { func (l *UserBasicInfoLogic) UserBasicInfo(req *types.Request, userinfo *auth.UserInfo) (resp *types.Response) {
// 必须返回response, 前端需要的是内部约定的Code码, 处理相关的逻辑. 例子(eg): resp.Set(501, "error") // 必须返回response, 前端需要的是内部约定的Code码, 处理相关的逻辑. 例子(eg): resp.Set(501, "error")
resp = &types.Response{} resp = &types.Response{}
// u := l.ctx.Value("userid").(int64)
u := l.ctx.Value("userid")
log.Println(u)
if userinfo.UserId == 0 { if userinfo.UserId == 0 {
resp = &types.Response{ resp = &types.Response{

View File

@ -2,6 +2,7 @@ package logic
import ( import (
"context" "context"
"time"
"fusenapi/home-user-auth/internal/svc" "fusenapi/home-user-auth/internal/svc"
"fusenapi/home-user-auth/internal/types" "fusenapi/home-user-auth/internal/types"
@ -26,30 +27,44 @@ func NewUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLog
} }
} }
func (l *UserLoginLogic) getJwtToken(secretKey string, iat, seconds, userId int64) (string, error) { func (l *UserLoginLogic) genJwtToken(accessSecret string, accessExpire, nowSec, userid int64) (string, error) {
claims := make(jwt.MapClaims) claims := make(jwt.MapClaims)
claims["exp"] = iat + seconds claims["exp"] = nowSec + accessExpire
claims["iat"] = iat claims["iat"] = nowSec
claims["userId"] = userId claims["userid"] = userid
token := jwt.New(jwt.SigningMethodHS256) token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims token.Claims = claims
return token.SignedString([]byte(secretKey)) return token.SignedString([]byte(accessSecret))
} }
func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin) (resp *types.Response) { func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin) (resp *types.Response, jwtToken string) {
// 必须返回response, 前端需要的是内部约定的Code码, 处理相关的逻辑. 例子(eg): resp.Set(501, "error") // 必须返回response, 前端需要的是内部约定的Code码, 处理相关的逻辑. 例子(eg): resp.Set(501, "error")
resp = &types.Response{} resp = &types.Response{}
userModel, err := model.NewFsUserModel(l.svcCtx.MysqlConn).FindOneByEmail(l.ctx, req.Name) userModel, err := model.NewFsUserModel(l.svcCtx.MysqlConn).FindOneByEmail(l.ctx, req.Name)
// log.Printf("%t %t %v", err, model.ErrNotFound, err == model.ErrNotFound) // log.Printf("%t %t %v", err, model.ErrNotFound, err == model.ErrNotFound)
if err == model.ErrNotFound { if err == model.ErrNotFound {
logx.Error(err) logx.Error(err)
resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error()) resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
return resp return resp, jwtToken
} }
// jwt 生成
nowSec := time.Now().Unix()
jwtToken, err = l.genJwtToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, userModel.Id)
if err != nil {
logx.Error(err)
resp.SetStatus(basic.CodeUnAuth)
return resp, jwtToken
}
data := &types.DataUserLogin{ data := &types.DataUserLogin{
Token: userModel.PasswordResetToken.String, Token: userModel.PasswordResetToken.String,
JwtToken: jwtToken,
} }
resp.SetStatus(basic.CodeOK, data) resp.SetStatus(basic.CodeOK, data)
return resp return resp, jwtToken
} }

View File

@ -31,7 +31,8 @@ type RequestUserLogin struct {
} }
type DataUserLogin struct { type DataUserLogin struct {
Token string `json:"token"` Token string `json:"token"` // 充值密码token
JwtToken string `json:"jwt_token"` // jwt 的Token
} }
type DataUserBasicInfo struct { type DataUserBasicInfo struct {
@ -74,9 +75,18 @@ type Response struct {
Data interface{} `json:"data"` Data interface{} `json:"data"`
} }
type ResponseJwt struct {
Code int `json:"code"`
Message string `json:"msg"`
Data interface{} `json:"data"`
AccessSecret string `json:"accessSecret"`
AccessExpire int64 `json:"accessExpire"`
}
type Auth struct { type Auth struct {
AccessSecret string `json:"AccessSecret"` AccessSecret string `json:"accessSecret"`
AccessExpire int `json:"AccessExpire"` AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
} }
// Set 设置Response的Code和Message值 // Set 设置Response的Code和Message值
@ -124,3 +134,49 @@ func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string,
resp.Data = data[0] resp.Data = data[0]
} }
} }
// Set 设置Response的Code和Message值
func (resp *ResponseJwt) Set(Code int, Message string) {
resp.Code = Code
resp.Message = Message
}
// Set 设置整个Response
func (resp *ResponseJwt) SetWithData(Code int, Message string, Data interface{}) {
resp.Code = Code
resp.Message = Message
resp.Data = Data
}
// SetMessage 设置Response的Message
func (resp *ResponseJwt) SetMessage(msg string) {
resp.Message = msg
}
// SetWithData 设置Data
func (resp *ResponseJwt) SetData(Data interface{}) {
resp.Data = Data
}
// SetWithData 设置Response的Code和Message值 带Data入参数
func (resp *ResponseJwt) SetCode(Code int) {
resp.Code = Code
}
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
func (resp *ResponseJwt) SetStatus(sr *basic.StatusResponse, data ...interface{}) {
resp.Code = sr.Code
resp.Message = sr.Message
if len(data) == 1 {
resp.Data = data[0]
}
}
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
func (resp *ResponseJwt) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) {
resp.Code = sr.Code
resp.Message = msg
if len(data) == 1 {
resp.Data = data[0]
}
}

View File

@ -13,10 +13,8 @@ import (
) )
var ( var (
fsCanteenTypeFieldNames = builder.RawFieldNames(&FsCanteenType{}) fsCanteenTypeFieldNames = builder.RawFieldNames(&FsCanteenType{})
fsCanteenTypeRows = strings.Join(fsCanteenTypeFieldNames, ",") fsCanteenTypeRows = strings.Join(fsCanteenTypeFieldNames, ",")
// fsCanteenTypeGetTypeRows = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`name`", "`sort`", "`created_at`", "`status`"), ",")
// fsCanteenTypeGetTypeRows = builder.RawFieldNames(&FsGetTypeCanteenType{})
fsCanteenTypeRowsExpectAutoSet = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") fsCanteenTypeRowsExpectAutoSet = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
fsCanteenTypeRowsWithPlaceHolder = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" fsCanteenTypeRowsWithPlaceHolder = strings.Join(stringx.Remove(fsCanteenTypeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
) )

View File

@ -13,3 +13,21 @@ type response {
Message string `json:"msg"` Message string `json:"msg"`
Data interface{} `json:"data"` Data interface{} `json:"data"`
} }
// responseJwt 统一返回码
type responseJwt {
Code int `json:"code"`
Message string `json:"msg"`
Data interface{} `json:"data"`
AccessSecret string `json:"accessSecret"`
AccessExpire int64 `json:"accessExpire"`
}
// Auth 认证结构
type Auth {
AccessSecret string `json:"accessSecret"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
}

View File

@ -14,6 +14,29 @@ type request {
// Name string `form:"name"` // parameters are auto validated // Name string `form:"name"` // parameters are auto validated
} }
service home-user-auth {
@handler UserLoginHandler
post /user/login(RequestUserLogin) returns (responseJwt);
@handler UserFontsHandler
get /user/fonts(request) returns (response);
@handler GetTypeHandler
get /user/get-type(request) returns (response);
@handler UserSaveBasicInfoHandler
post /user/basic-info(RequestBasicInfoForm) returns (response);
}
@server(
jwt: Auth
)
service home-user-auth {
@handler UserBasicInfoHandler
get /user/basic-info(request) returns (response);
}
type RequestBasicInfoForm { type RequestBasicInfoForm {
FirstName string `form:"first_name,optional" db:"first_name"` // FirstName FirstName string `form:"first_name,optional" db:"first_name"` // FirstName
LastName string `form:"last_name,optional" db:"last_name"` // LastName LastName string `form:"last_name,optional" db:"last_name"` // LastName
@ -40,7 +63,8 @@ type RequestUserLogin {
// UserLoginHandler 用户登录请求结构 // UserLoginHandler 用户登录请求结构
type DataUserLogin { type DataUserLogin {
Token string `json:"token"` Token string `json:"token"` // 充值密码token
JwtToken string `json:"jwt_token"` // jwt 的Token
} }
// UserBasicInfoHandler 返回data结构 // UserBasicInfoHandler 返回data结构
@ -78,25 +102,3 @@ type DataGetType {
Id int64 `db:"id" json:"key"` // ID Id int64 `db:"id" json:"key"` // ID
Name string `db:"name" json:"name"` // 餐厅名字 Name string `db:"name" json:"name"` // 餐厅名字
} }
service home-user-auth {
@handler UserLoginHandler
post /user/login(RequestUserLogin) returns (response);
@handler UserFontsHandler
get /user/fonts(request) returns (response);
@handler GetTypeHandler
get /user/get-type(request) returns (response);
@handler UserSaveBasicInfoHandler
post /user/basic-info(RequestBasicInfoForm) returns (response);
}
@server(
jwt: Auth
)
service home-user-auth {
@handler UserBasicInfoHandler
get /user/basic-info(request) returns (response);
}