finish: gorm序列化

This commit is contained in:
eson 2023-06-14 18:17:45 +08:00
parent 50bca808f1
commit 6a2cfb14e9
26 changed files with 841 additions and 143 deletions

17
ddl/fs_guest.sql Normal file
View File

@ -0,0 +1,17 @@
-- fusentest.fs_guest definition
CREATE TABLE `fs_guest` (
`guest_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '游客ID',
`auth_key` varchar(512) NOT NULL DEFAULT '' COMMENT 'jwt token',
`status` tinyint(3) unsigned DEFAULT '1' COMMENT '1正常 0不正常',
`is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1删除',
`created_at` int(11) NOT NULL DEFAULT '0' COMMENT '添加时间',
`updated_at` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`is_open_render` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否打开个性化渲染1开启0关闭',
`is_thousand_face` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已经存在千人千面1存在0不存在',
`is_low_rendering` tinyint(1) unsigned zerofill NOT NULL DEFAULT '0' COMMENT '是否开启低渲染模型渲染',
`is_remove_bg` tinyint(1) NOT NULL DEFAULT '1' COMMENT '用户上传logo是否去除背景',
PRIMARY KEY (`guest_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='游客表';

View File

@ -1,2 +1,4 @@
#! /bin/bash
goctl model mysql ddl --src ./ddl/$1.sql --dir model/ --home ./goctl_template
# goctl model mysql ddl --src ./ddl/$1.sql --dir model/ --home ./goctl_template
go run generator/main.go -name $1

232
generator/main.go Normal file
View File

@ -0,0 +1,232 @@
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"github.com/zeromicro/ddl-parser/parser"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
var targerDir = "ddl"
var genDir = "model/gmodel_gen"
func toPascalCase(s string) string {
words := strings.Split(s, "_")
for i, word := range words {
words[i] = cases.Title(language.English).String(strings.ToLower(word))
}
return strings.Join(words, "")
}
const (
_ int = iota
LongVarBinary
LongVarChar
GeometryCollection
GeomCollection
LineString
MultiLineString
MultiPoint
MultiPolygon
Point
Polygon
Json
Geometry
Enum
Set
Bit
Time
Timestamp
DateTime
Binary
VarBinary
Blob
Year
Decimal
Dec
Fixed
Numeric
Float
Float4
Float8
Double
Real
TinyInt
SmallInt
MediumInt
Int
Integer
BigInt
MiddleInt
Int1
Int2
Int3
Int4
Int8
Date
TinyBlob
MediumBlob
LongBlob
Bool
Boolean
Serial
NVarChar
NChar
Char
Character
VarChar
TinyText
Text
MediumText
LongText
)
var SQLTypeToGoTypeMap = map[int]string{
LongVarBinary: "[]byte",
Binary: "[]byte",
VarBinary: "[]byte",
Blob: "[]byte",
TinyBlob: "[]byte",
MediumBlob: "[]byte",
LongBlob: "[]byte",
LongVarChar: "*string",
NVarChar: "*string",
NChar: "*string",
Char: "*string",
Character: "*string",
VarChar: "*string",
TinyText: "*string",
Text: "*string",
MediumText: "*string",
LongText: "*string",
Time: "*time.Time",
Timestamp: "*time.Time",
DateTime: "*time.Time",
Date: "*time.Time",
Year: "*int64",
TinyInt: "*int64",
SmallInt: "*int64",
MediumInt: "*int64",
Int: "*int64",
Integer: "*int64",
BigInt: "*int64",
MiddleInt: "*int64",
Int1: "*int64",
Int2: "*int64",
Int3: "*int64",
Int4: "*int64",
Int8: "*int64",
Serial: "*int64",
Decimal: "*float64",
Dec: "*float64",
Fixed: "*float64",
Numeric: "*float64",
Float: "*float64",
Float4: "*float64",
Float8: "*float64",
Double: "*float64",
Real: "*float64",
Bool: "*bool",
Boolean: "*bool",
}
func main() {
var name string
flag.StringVar(&name, "name", "", "输入需要序列化的ddl文件名, 不需要后缀.ddl")
flag.Parse()
p, err := filepath.Abs(fmt.Sprintf("%s/%s.sql", targerDir, name))
if err != nil {
panic(err)
}
ddlf, err := os.Open(p)
if err != nil {
panic(err)
}
ddlfilestr, err := ioutil.ReadAll(ddlf)
if err != nil {
panic(err)
}
// PRIMARY KEY (`guest_id`) USING BTREE
re := regexp.MustCompile("PRIMARY\\s+KEY\\s+\\(\\s*`([^`]+)`\\s*\\)|`([^`]+)` [^\n]+PRIMARY\\s+KEY\\s+")
matches := re.FindStringSubmatch(string(ddlfilestr))
PrimaryStr := ""
if len(matches) > 0 {
PrimaryStr = matches[1]
}
// 匹配到主键定义
parser.NewParser()
result, err := parser.NewParser().From(p)
if err != nil {
panic(err)
}
fcontent := "package model\nimport \"gorm.io/gorm\"\n"
for _, table := range result {
structstr := "type %s struct {%s\n}\n"
tableName := toPascalCase(table.Name)
fieldstr := ""
for _, col := range table.Columns {
fieldName := toPascalCase(col.Name)
typeName := SQLTypeToGoTypeMap[col.DataType.Type()]
tagstr := "`gorm:"
if col.Name == PrimaryStr {
tagstr += "\"primary_key\""
typeName = typeName[1:]
} else {
tagstr += "\"\""
}
tagstr += fmt.Sprintf(" json:\"%s\"`", col.Name)
fieldColStr := fmt.Sprintf("\n%s %s %s// %s", fieldName, typeName, tagstr, col.Constraint.Comment)
fieldstr += fieldColStr
}
fcontent += fmt.Sprintf(structstr, tableName, fieldstr)
modelstr := fmt.Sprintf(`type %sModel struct {db *gorm.DB}`, tableName)
fcontent += modelstr
fcontent += "\n"
newfuncstr := fmt.Sprintf(`func New%sModel(db *gorm.DB) *%sModel {return &%sModel{db}}`, tableName, tableName, tableName)
fcontent += newfuncstr
fcontent += "\n"
genGoFileName := fmt.Sprintf("%s/%s_gen.go", genDir, table.Name)
f, err := os.OpenFile(genGoFileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
f.WriteString(fcontent)
err = f.Close()
if err != nil {
panic(err)
}
err = exec.Command("gofmt", "-w", genGoFileName).Run()
if err != nil {
panic(err)
}
// log.Println(fcontent)
}
}

15
generator/main_test.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"os"
"testing"
)
func TestMain(t *testing.T) {
// args := []string{"-name", "fs_guest"}
targerDir = "../" + targerDir
genDir = "../" + genDir
os.Args = []string{"cmd", "-name=fs_guest"}
main()
}

10
go.mod
View File

@ -12,11 +12,16 @@ require (
gorm.io/gorm v1.25.1
)
require (
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
)
require (
github.com/474420502/requests v1.32.1
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/tidwall/gjson v1.12.0 // indirect
github.com/tidwall/gjson v1.12.0
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
)
@ -47,6 +52,7 @@ require (
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/zeromicro/ddl-parser v1.0.4
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
@ -60,7 +66,7 @@ require (
go.uber.org/automaxprocs v1.5.2 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/text v0.9.0
google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197 // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect

6
go.sum
View File

@ -41,6 +41,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
github.com/alicebob/miniredis/v2 v2.30.2 h1:lc1UAUT9ZA7h4srlfBmBt2aorm5Yftk9nBjxz7EyY9I=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec h1:EEyRvzmpEUZ+I8WmD5cw/vY8EqhambkOqy5iFr0908A=
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521184019-c5ad59b459ec/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
@ -178,6 +180,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -235,6 +239,8 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE=
github.com/zeromicro/ddl-parser v1.0.4 h1:fzU0ZNfV/a6T/WO8TvZZeJE9hmdt3qHvVUsW1X9SGJQ=
github.com/zeromicro/ddl-parser v1.0.4/go.mod h1:ISU/8NuPyEpl9pa17Py9TBPetMjtsiHrb9f5XGiYbo8=
github.com/zeromicro/go-zero v1.5.2 h1:vpMlZacCMtgdtYzKI3OMyhS6mZ9UQctiAh0J7gIq31I=
github.com/zeromicro/go-zero v1.5.2/go.mod h1:ndCd1nMMAdEMZgPfdm1fpavHUdBW0ykB6ckCRaSG10w=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=

View File

@ -15,28 +15,40 @@ import (
func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
{{if .HasRequest}}var req types.{{.RequestType}}
@ -53,7 +65,6 @@ func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
{{if .HasResp}}resp{{end}} := l.{{.Call}}({{if .HasRequest}}&req, {{end}}userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
{{if .HasResp}}httpx.OkJsonCtx(r.Context(), w, resp){{else}}httpx.Ok(w){{end}}
} else {

24
model/fsguestmodel.go Executable file
View File

@ -0,0 +1,24 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ FsGuestModel = (*customFsGuestModel)(nil)
type (
// FsGuestModel is an interface to be customized, add more methods here,
// and implement the added methods in customFsGuestModel.
FsGuestModel interface {
fsGuestModel
}
customFsGuestModel struct {
*defaultFsGuestModel
}
)
// NewFsGuestModel returns a model for the database table.
func NewFsGuestModel(conn sqlx.SqlConn) FsGuestModel {
return &customFsGuestModel{
defaultFsGuestModel: newFsGuestModel(conn),
}
}

92
model/fsguestmodel_gen.go Executable file
View File

@ -0,0 +1,92 @@
// Code generated by goctl. DO NOT EDIT.
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
fsGuestFieldNames = builder.RawFieldNames(&FsGuest{})
fsGuestRows = strings.Join(fsGuestFieldNames, ",")
fsGuestRowsExpectAutoSet = strings.Join(stringx.Remove(fsGuestFieldNames, "`guest_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
fsGuestRowsWithPlaceHolder = strings.Join(stringx.Remove(fsGuestFieldNames, "`guest_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
fsGuestModel interface {
Insert(ctx context.Context, data *FsGuest) (sql.Result, error)
FindOne(ctx context.Context, guestId int64) (*FsGuest, error)
Update(ctx context.Context, data *FsGuest) error
Delete(ctx context.Context, guestId int64) error
}
defaultFsGuestModel struct {
conn sqlx.SqlConn
table string
}
FsGuest struct {
GuestId int64 `db:"guest_id"` // 游客ID
AuthKey string `db:"auth_key"` // jwt token
Status int64 `db:"status"` // 1正常 0不正常
IsDel int64 `db:"is_del"` // 是否删除 1删除
CreatedAt int64 `db:"created_at"` // 添加时间
UpdatedAt int64 `db:"updated_at"` // 更新时间
IsOpenRender int64 `db:"is_open_render"` // 是否打开个性化渲染1开启0关闭
IsThousandFace int64 `db:"is_thousand_face"` // 是否已经存在千人千面1存在0不存在
IsLowRendering int64 `db:"is_low_rendering"` // 是否开启低渲染模型渲染
IsRemoveBg int64 `db:"is_remove_bg"` // 用户上传logo是否去除背景
}
)
func newFsGuestModel(conn sqlx.SqlConn) *defaultFsGuestModel {
return &defaultFsGuestModel{
conn: conn,
table: "`fs_guest`",
}
}
func (m *defaultFsGuestModel) Delete(ctx context.Context, guestId int64) error {
query := fmt.Sprintf("delete from %s where `guest_id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, guestId)
return err
}
func (m *defaultFsGuestModel) FindOne(ctx context.Context, guestId int64) (*FsGuest, error) {
query := fmt.Sprintf("select %s from %s where `guest_id` = ? limit 1", fsGuestRows, m.table)
var resp FsGuest
err := m.conn.QueryRowCtx(ctx, &resp, query, guestId)
switch err {
case nil:
return &resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultFsGuestModel) Insert(ctx context.Context, data *FsGuest) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, fsGuestRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.AuthKey, data.Status, data.IsDel, data.IsOpenRender, data.IsThousandFace, data.IsLowRendering, data.IsRemoveBg)
return ret, err
}
func (m *defaultFsGuestModel) Update(ctx context.Context, data *FsGuest) error {
query := fmt.Sprintf("update %s set %s where `guest_id` = ?", m.table, fsGuestRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.AuthKey, data.Status, data.IsDel, data.IsOpenRender, data.IsThousandFace, data.IsLowRendering, data.IsRemoveBg, data.GuestId)
return err
}
func (m *defaultFsGuestModel) tableName() string {
return m.table
}

14
model/gmodel/fsguestmodel.go Executable file
View File

@ -0,0 +1,14 @@
package gmodel
type FsGuest struct {
GuestId int64 `gorm:"" json:"guest_id"` // ID
AuthKey *string `gorm: json:"auth_key"` // jwt token
Status *int64 `gorm: json:"status"` // 1正常 0不正常
IsDel *int64 `gorm: json:"is_del"` // 是否删除 1删除
CreatedAt *int64 `gorm: json:"created_at"` // 添加时间
UpdatedAt *int64 `gorm: json:"updated_at"` // 更新时间
IsOpenRender *int64 `gorm: json:"is_open_render"` // 是否打开个性化渲染1开启0关闭
IsThousandFace *int64 `gorm: json:"is_thousand_face"` // 是否已经存在千人千面1存在0不存在
IsLowRendering *int64 `gorm: json:"is_low_rendering"` // 是否开启低渲染模型渲染
IsRemoveBg *int64 `gorm: json:"is_remove_bg"` // 用户上传logo是否去除背景
}

View File

@ -0,0 +1,19 @@
package model
import "gorm.io/gorm"
type FsGuest struct {
GuestId int64 `gorm:"primary_key" json:"guest_id"` // 游客ID
AuthKey *string `gorm:"" json:"auth_key"` // jwt token
Status *int64 `gorm:"" json:"status"` // 1正常 0不正常
IsDel *int64 `gorm:"" json:"is_del"` // 是否删除 1删除
CreatedAt *int64 `gorm:"" json:"created_at"` // 添加时间
UpdatedAt *int64 `gorm:"" json:"updated_at"` // 更新时间
IsOpenRender *int64 `gorm:"" json:"is_open_render"` // 是否打开个性化渲染1开启0关闭
IsThousandFace *int64 `gorm:"" json:"is_thousand_face"` // 是否已经存在千人千面1存在0不存在
IsLowRendering *int64 `gorm:"" json:"is_low_rendering"` // 是否开启低渲染模型渲染
IsRemoveBg *int64 `gorm:"" json:"is_remove_bg"` // 用户上传logo是否去除背景
}
type FsGuestModel struct{ db *gorm.DB }
func NewFsGuestModel(db *gorm.DB) *FsGuestModel { return &FsGuestModel{db} }

View File

@ -0,0 +1,78 @@
package handler
import (
"errors"
"net/http"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/server/home-user-auth/internal/logic"
"fusenapi/server/home-user-auth/internal/svc"
"fusenapi/server/home-user-auth/internal/types"
)
func AcceptCookieHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
// 如果端点有请求结构体则使用httpx.Parse方法从HTTP请求体中解析请求数据
if err := httpx.Parse(r, &req); err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 510,
Message: "parameter error",
})
logx.Info(err)
return
}
// 创建一个业务逻辑层实例
l := logic.NewAcceptCookieLogic(r.Context(), svcCtx)
resp := l.AcceptCookie(&req, userinfo)
// 如果响应不为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)
}
}
}

View File

@ -17,6 +17,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/user/login",
Handler: UserLoginHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/user/accept-cookie",
Handler: AcceptCookieHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/user/fonts",
@ -42,17 +47,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/user/basic-info",
Handler: UserBasicInfoHandler(serverCtx),
},
},
)
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/user/address-list",
Handler: UserAddressListHandler(serverCtx),
},
},
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
)
}

View File

@ -15,15 +15,31 @@ import (
"fusenapi/server/home-user-auth/internal/types"
)
var wantJwt = true
func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var userinfo *auth.UserInfo
var err error
if wantJwt {
userinfo, err = auth.ParseJwtToken(w, r, &svcCtx.Config.Auth.AccessSecret)
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
@ -32,6 +48,9 @@ func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
@ -48,7 +67,6 @@ func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserAddressListLogic(r.Context(), svcCtx)
resp := l.UserAddressList(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -17,28 +17,40 @@ import (
func UserBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
@ -55,7 +67,6 @@ func UserBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserBasicInfoLogic(r.Context(), svcCtx)
resp := l.UserBasicInfo(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -17,28 +17,40 @@ import (
func UserFontsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
@ -55,7 +67,6 @@ func UserFontsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserFontsLogic(r.Context(), svcCtx)
resp := l.UserFonts(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -17,28 +17,40 @@ import (
func UserGetTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
@ -55,7 +67,6 @@ func UserGetTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserGetTypeLogic(r.Context(), svcCtx)
resp := l.UserGetType(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -17,28 +17,40 @@ import (
func UserSaveBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.RequestBasicInfoForm
@ -55,7 +67,6 @@ func UserSaveBasicInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserSaveBasicInfoLogic(r.Context(), svcCtx)
resp := l.UserSaveBasicInfo(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -17,28 +17,40 @@ import (
func UserStatusConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 解析jwtToken
var (
// 定义错误变量
err error
// 定义用户信息变量
userinfo *auth.UserInfo
)
// 解析JWT token,并对空用户进行判断
claims, err := svcCtx.ParseJwtToken(r)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
// 如果解析JWT token出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
Code: 401, // 返回401状态码,表示未授权
Message: "unauthorized", // 返回未授权信息
})
logx.Info("unauthorized:", err.Error())
logx.Info("unauthorized:", err.Error()) // 记录错误日志
return
}
// 从Token里获取对应的信息
userinfo, err := auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
if claims != nil {
// 从token中获取对应的用户信息
userinfo, err = auth.GetUserInfoFormMapClaims(claims)
// 如果获取用户信息出错,则返回未授权的JSON响应并记录错误消息
if err != nil {
httpx.OkJsonCtx(r.Context(), w, &basic.Response{
Code: 401,
Message: "unauthorized",
})
logx.Info("unauthorized:", err.Error())
return
}
} else {
// 如果claims为nil,则认为用户身份为白板用户
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
}
var req types.Request
@ -55,7 +67,6 @@ func UserStatusConfigHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
l := logic.NewUserStatusConfigLogic(r.Context(), svcCtx)
resp := l.UserStatusConfig(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
// 否则发送500内部服务器错误的JSON响应并记录错误消息logx.Error。
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)
} else {

View File

@ -0,0 +1,38 @@
package logic
import (
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"context"
"fusenapi/server/home-user-auth/internal/svc"
"fusenapi/server/home-user-auth/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type AcceptCookieLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewAcceptCookieLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AcceptCookieLogic {
return &AcceptCookieLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *AcceptCookieLogic) AcceptCookie(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null
idtyp := userinfo.GetIdType()
if idtyp == auth.IDTYPE_Guest {
return resp.SetStatus(basic.CodeDupGuestErr)
}
return resp.SetStatus(basic.CodeOK)
}

View File

@ -48,7 +48,7 @@ func (l *UserLoginLogic) UserLogin(req *types.RequestUserLogin) (resp *basic.Res
// 如果密码匹配,则生成 JWT Token。
nowSec := time.Now().Unix()
jwtToken, err = auth.GenerateJwtToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, int(userModel.Id))
jwtToken, err = auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, int64(userModel.Id), 0)
// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
if err != nil {

View File

@ -24,8 +24,8 @@ func NewServiceContext(c config.Config) *ServiceContext {
func (svcCxt *ServiceContext) ParseJwtToken(r *http.Request) (jwt.MapClaims, error) {
AuthKey := r.Header.Get("Authorization")
if len(AuthKey) <= 50 {
return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey)))
if AuthKey == "" {
return nil, nil
}
token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) {

View File

@ -18,6 +18,9 @@ service home-user-auth {
@handler UserLoginHandler
post /user/login(RequestUserLogin) returns (response);
@handler AcceptCookieHandler
post /user/accept-cookie(request) returns (response);
@handler UserFontsHandler
get /user/fonts(request) returns (response);
@ -33,17 +36,9 @@ service home-user-auth {
@handler UserBasicInfoHandler
get /user/basic-info(request) returns (response);
// @handler UserAddressListHandler
// get /user/address-list(request) returns (response);
}
@server(
jwt: Auth
)
service home-user-auth {
@handler UserAddressListHandler
get /user/address-list(request) returns (response);
}
type RequestBasicInfoForm {

View File

@ -8,17 +8,41 @@ import (
"net/http"
"github.com/golang-jwt/jwt"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx"
)
type IDTYPE int
const (
// 白板用户, 以观众身份命名, 没有接收Cookie, 没有拿到guest_id的用户
IDTYPE_Onlooker IDTYPE = 0
// 登录用户
IDTYPE_User IDTYPE = 1
// 游客 接收授权拿到guest_id的用户
IDTYPE_Guest IDTYPE = 2
)
type UserInfo struct {
UserId int64 `json:"userid"`
UserId int64 `json:"user_id"`
GuestId int64 `json:"guest_id"`
}
// GetIdType 用户确认用户身份类型
func (info *UserInfo) GetIdType() IDTYPE {
if info.UserId != 0 {
return IDTYPE_User
}
if info.GuestId != 0 {
return IDTYPE_Guest
}
return IDTYPE_Onlooker
}
// 获取登录信息
func GetUserInfoFormCtx(ctx context.Context) UserInfo {
uid, err := ctx.Value("userid").(json.Number).Int64()
uid, err := ctx.Value("user_id").(json.Number).Int64()
if err != nil {
logx.Error("parse uid form context err:", err.Error())
return UserInfo{}
@ -28,43 +52,60 @@ func GetUserInfoFormCtx(ctx context.Context) UserInfo {
// 获取登录信息
func GetUserInfoFormMapClaims(claims jwt.MapClaims) (*UserInfo, error) {
if userid, ok := claims["userid"]; ok {
userinfo := &UserInfo{}
if userid, ok := claims["user_id"]; ok {
uid, ok := userid.(float64)
if !ok {
err := errors.New(fmt.Sprint("parse uid form context err:", userid))
logx.Error("parse uid form context err:", err)
return nil, err
}
return &UserInfo{UserId: int64(uid)}, nil
userinfo.UserId = int64(uid)
} else {
err := errors.New(`userid not in claims`)
logx.Error(`userid not in claims`)
return nil, err
}
if guestid, ok := claims["guest_id"]; ok {
gid, ok := guestid.(float64)
if !ok {
err := errors.New(fmt.Sprint("parse guestid form context err:", guestid))
logx.Error("parse guestid form context err:", err)
return nil, err
}
userinfo.GuestId = int64(gid)
} else {
err := errors.New(`userid not in claims`)
logx.Error(`userid not in claims`)
return nil, err
}
return userinfo, nil
}
func GenerateJwtToken(accessSecret string, accessExpire, nowSec int64, userid int) (string, error) {
func GenerateJwtToken(accessSecret *string, accessExpire, nowSec int64, userid int64, guestid int64) (string, error) {
claims := make(jwt.MapClaims)
claims["exp"] = nowSec + accessExpire
claims["iat"] = nowSec
claims["userid"] = userid
if userid == 0 {
u, err := uuid.NewUUID()
if err != nil {
logx.Error(err)
return "", err
}
claims["guestid"] = u.String() // TODO: 未完成
if userid == 0 && guestid == 0 {
err := errors.New("userid and guestid cannot be 0 at the same time")
logx.Error(err)
return "", err
}
claims["user_id"] = userid
claims["guest_id"] = guestid
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = claims
return token.SignedString([]byte(accessSecret))
return token.SignedString([]byte(*accessSecret))
}
func ParseJwtToken(w http.ResponseWriter, r *http.Request, AccessSecret *string) (*UserInfo, error) {
// 解析jwtToken
claims, err := getJwtClaims(r, AccessSecret)
claims, err := getJwtClaimsFromRequest(r, AccessSecret)
// 如果解析出错则返回未授权的JSON响应并记录错误消息
if err != nil {
// httpx.OkJsonCtx(r.Context(), w, &basic.Response{
@ -89,12 +130,17 @@ func ParseJwtToken(w http.ResponseWriter, r *http.Request, AccessSecret *string)
return userinfo, err
}
func getJwtClaims(r *http.Request, AccessSecret *string) (jwt.MapClaims, error) {
func getJwtClaimsFromRequest(r *http.Request, AccessSecret *string) (jwt.MapClaims, error) {
AuthKey := r.Header.Get("Authorization")
if len(AuthKey) <= 50 {
return nil, errors.New(fmt.Sprint("Error parsing token, len:", len(AuthKey)))
}
return getJwtClaims(AuthKey, AccessSecret)
}
func getJwtClaims(AuthKey string, AccessSecret *string) (jwt.MapClaims, error) {
token, err := jwt.Parse(AuthKey, func(token *jwt.Token) (interface{}, error) {
// 检查签名方法是否为 HS256
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {

30
utils/auth/user_test.go Normal file
View File

@ -0,0 +1,30 @@
package auth
import (
"testing"
"time"
)
// TestGenJwt 测试jwt序列化
func TestGenJwt(t *testing.T) {
now := time.Now().Unix()
secret := "fusen123"
a, err := GenerateJwtToken(&secret, 3600, now, 123, 1234)
if err != nil {
t.Error(err)
}
// log.Println(a)
claims, err := getJwtClaims(a, &secret)
if err != nil {
t.Error(err)
}
userinfo, err := GetUserInfoFormMapClaims(claims)
if err != nil {
t.Error(err)
}
if userinfo.UserId != 123 || userinfo.GuestId != 1234 {
t.Error(userinfo)
}
// log.Println(claims)
}

View File

@ -13,7 +13,8 @@ var (
CodeServiceErr = &StatusResponse{510, "server logic error"} // server logic 错误
CodeUnAuth = &StatusResponse{401, "unauthorized"} // 未授权
CodeUpdateErr = &StatusResponse{5000, "update database error"} // update database logic 错误
CodeUpdateErr = &StatusResponse{5000, "update database error"} // update database logic 错误
CodeDupGuestErr = &StatusResponse{5001, "the user is already a guest user and does not need to apply again"} // 用户已经是guest用户不需要重复申请 错误
)
type Response struct {