新增代理服务的离线接口,优化认证逻辑,代理服务表添加状态字段

This commit is contained in:
2025-05-13 15:26:40 +08:00
parent 60df1548f0
commit 0d40c5aa09
8 changed files with 88 additions and 17 deletions

View File

@@ -71,6 +71,11 @@ func main() {
return err
}
proxySecret, err := bcrypt.GenerateFromPassword([]byte("proxy"), bcrypt.DefaultCost)
if err != nil {
return err
}
err = q.Client.
Select(
q.Client.ClientID,
@@ -96,6 +101,17 @@ func main() {
GrantClient: true,
Spec: int32(client2.SpecTrusted),
Name: "异步任务处理服务",
}, &m.Client{
ClientID: "proxy",
ClientSecret: string(proxySecret),
GrantClient: true,
Spec: int32(client2.SpecTrusted),
Name: "代理转发服务",
}, &m.Client{
ClientID: "edge",
GrantClient: true,
Spec: int32(client2.SpecWeb),
Name: "代理边缘节点",
})
if err != nil {
return err

View File

@@ -516,14 +516,17 @@ create table proxy (
version int not null,
name varchar(255) not null unique,
host varchar(255) not null,
type int not null default 0,
secret varchar(255),
created_at timestamp default current_timestamp,
updated_at timestamp default current_timestamp,
type int not null,
status int not null,
created_at timestamp default current_timestamp,
updated_at timestamp default current_timestamp,
deleted_at timestamp
);
create index proxy_name_index on proxy (name);
create index proxy_host_index on proxy (host);
create index proxy_type_index on proxy (type);
create index proxy_status_index on proxy (status);
create index proxy_deleted_at_index on proxy (deleted_at);
-- proxy表字段注释
@@ -534,6 +537,7 @@ comment on column proxy.name is '代理服务名称';
comment on column proxy.host is '代理服务地址';
comment on column proxy.type is '代理服务类型1-三方2-自有';
comment on column proxy.secret is '代理服务密钥';
comment on column proxy.status is '代理服务状态0-离线1-在线';
comment on column proxy.created_at is '创建时间';
comment on column proxy.updated_at is '更新时间';
comment on column proxy.deleted_at is '删除时间';

View File

@@ -43,11 +43,13 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
var header = c.Get("Authorization")
var split = strings.Split(header, " ")
if len(split) != 2 {
slog.Debug("Authorization 头格式不正确")
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
}
var token = split[1]
var token = strings.TrimSpace(split[1])
if token == "" {
slog.Debug("提供的令牌为空")
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
}
@@ -63,7 +65,7 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
}
case "Basic":
if !slices.Contains(types, PayloadSecuredServer) {
if !slices.Contains(types, PayloadInternalServer) {
slog.Debug("禁止使用 Basic 认证方式")
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
}
@@ -74,18 +76,18 @@ func Protect(c *fiber.Ctx, types []PayloadType, permissions []string) (*Context,
}
default:
slog.Debug("无效的认证方式")
slog.Debug("无效的认证方式", "method", split[0])
return nil, fiber.NewError(fiber.StatusUnauthorized, "无效的令牌")
}
// 检查权限
if !slices.Contains(types, auth.Payload.Type) {
slog.Debug("无效的认证主体")
slog.Debug("无效的负载类型", "except", types, "actual", auth.Payload.Type)
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
}
if len(permissions) > 0 && !auth.AnyPermission(permissions...) {
slog.Debug("无效的认证权限")
slog.Debug("无效的认证权限", "except", permissions, "actual", auth.Permissions)
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
}
@@ -114,15 +116,12 @@ func authBasic(_ context.Context, token string) (*Context, error) {
// 解析 Basic 认证信息
var base, err = base64.RawURLEncoding.DecodeString(token)
if err != nil {
slog.Debug(err.Error())
return nil, err
return nil, errors.New("令牌格式错误,无法解析令牌")
}
var split = strings.Split(string(base), ":")
if len(split) != 2 {
msg := "无法解析 Basic 认证信息"
slog.Debug(msg)
return nil, errors.New(msg)
return nil, errors.New("令牌格式错误,必须是 <client_id>:<client_secret> 格式")
}
var clientID = split[0]
@@ -151,7 +150,7 @@ func authBasic(_ context.Context, token string) (*Context, error) {
return &Context{
Payload: Payload{
Id: client.ID,
Type: PayloadSecuredServer,
Type: PayloadTypeFromClientSpec(client2.Spec(client.Spec)),
Name: client.Name,
Avatar: client.Icon,
},

View File

@@ -65,6 +65,8 @@ func (t PayloadType) ToStr() string {
return "cpub"
case PayloadSecuredServer:
return "ccnf"
case PayloadInternalServer:
return "inte"
default:
return "none"
}
@@ -80,6 +82,8 @@ func PayloadTypeFromStr(name string) PayloadType {
return PayloadPublicServer
case "ccnf":
return PayloadSecuredServer
case "inte":
return PayloadInternalServer
default:
return PayloadNone
}

View File

@@ -3,6 +3,7 @@ package handlers
import (
"github.com/gofiber/fiber/v2"
"gorm.io/gorm/clause"
"log/slog"
auth2 "platform/web/auth"
proxy2 "platform/web/domains/proxy"
g "platform/web/globals"
@@ -10,7 +11,9 @@ import (
q "platform/web/queries"
)
type RegisterProxyReq struct {
// region OnlineProxy
type OnlineProxyReq struct {
Name string `json:"name" validate:"required"`
Version int `json:"version" validate:"required"`
}
@@ -26,13 +29,14 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
}
// 验证请求参数
var req = new(RegisterProxyReq)
var req = new(OnlineProxyReq)
err = g.Validator.Validate(c, req)
if err != nil {
return err
}
// 创建代理
slog.Debug("注册转发服务", "ip", c.IP())
err = q.Proxy.
Clauses(clause.OnConflict{
UpdateAll: true,
@@ -45,6 +49,7 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
Version: int32(req.Version),
Host: c.IP(),
Type: int32(proxy2.TypeSelfHosted),
Status: 1,
})
if err != nil {
return err
@@ -52,3 +57,40 @@ func OnlineProxy(c *fiber.Ctx) (err error) {
return nil
}
// endregion
// region OfflineProxy
type OfflineProxyReq struct {
Name string `json:"name" validate:"required"`
}
func OfflineProxy(c *fiber.Ctx) (err error) {
// 检查接口权限
_, err = auth2.NewProtect(c).Payload(
auth2.PayloadInternalServer,
).Do()
if err != nil {
return err
}
// 验证请求参数
var req = new(OfflineProxyReq)
err = g.Validator.Validate(c, req)
if err != nil {
return err
}
// 下线转发服务
_, err = q.Proxy.
Where(q.Proxy.Name.Eq(req.Name)).
UpdateSimple(q.Proxy.Status.Value(0))
if err != nil {
return err
}
return nil
}
// endregion

View File

@@ -23,6 +23,7 @@ type Proxy struct {
CreatedAt orm.LocalDateTime `gorm:"column:created_at;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_at"` // 创建时间
UpdatedAt orm.LocalDateTime `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` // 更新时间
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;comment:删除时间" json:"deleted_at"` // 删除时间
Status int32 `gorm:"column:status;not null;comment:代理服务状态0-离线1-在线" json:"status"` // 代理服务状态0-离线1-在线
Edges []Edge `gorm:"foreignKey:ProxyID;references:ID" json:"edges"`
}

View File

@@ -36,6 +36,7 @@ func newProxy(db *gorm.DB, opts ...gen.DOOption) proxy {
_proxy.CreatedAt = field.NewField(tableName, "created_at")
_proxy.UpdatedAt = field.NewField(tableName, "updated_at")
_proxy.DeletedAt = field.NewField(tableName, "deleted_at")
_proxy.Status = field.NewInt32(tableName, "status")
_proxy.Edges = proxyHasManyEdges{
db: db.Session(&gorm.Session{}),
@@ -60,6 +61,7 @@ type proxy struct {
CreatedAt field.Field // 创建时间
UpdatedAt field.Field // 更新时间
DeletedAt field.Field // 删除时间
Status field.Int32 // 代理服务状态0-离线1-在线
Edges proxyHasManyEdges
fieldMap map[string]field.Expr
@@ -86,6 +88,7 @@ func (p *proxy) updateTableName(table string) *proxy {
p.CreatedAt = field.NewField(table, "created_at")
p.UpdatedAt = field.NewField(table, "updated_at")
p.DeletedAt = field.NewField(table, "deleted_at")
p.Status = field.NewInt32(table, "status")
p.fillFieldMap()
@@ -102,7 +105,7 @@ func (p *proxy) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (p *proxy) fillFieldMap() {
p.fieldMap = make(map[string]field.Expr, 10)
p.fieldMap = make(map[string]field.Expr, 11)
p.fieldMap["id"] = p.ID
p.fieldMap["version"] = p.Version
p.fieldMap["name"] = p.Name
@@ -112,6 +115,7 @@ func (p *proxy) fillFieldMap() {
p.fieldMap["created_at"] = p.CreatedAt
p.fieldMap["updated_at"] = p.UpdatedAt
p.fieldMap["deleted_at"] = p.DeletedAt
p.fieldMap["status"] = p.Status
}

View File

@@ -66,6 +66,7 @@ func ApplyRouters(app *fiber.App) {
// 网关
proxy := api.Group("/proxy")
proxy.Post("/online", handlers.OnlineProxy)
proxy.Post("/offline", handlers.OfflineProxy)
// 节点
edge := api.Group("/edge")