Some checks failed
Build docker and publish / prepare (20.15.1) (push) Successful in 10s
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.admin image_name:ppanel-admin name:admin]) (push) Successful in 1m16s
Build docker and publish / deploy (push) Has been cancelled
Build docker and publish / notify (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.rpc-core image_name:ppanel-rpc-core name:rpc-core]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.scheduler image_name:ppanel-scheduler name:scheduler]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.node image_name:ppanel-node name:node]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.queue image_name:ppanel-queue name:queue]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.api image_name:ppanel-api name:api]) (push) Has been cancelled
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
// Code scaffolded by goctl. Safe to edit.
|
|
// goctl 1.9.2
|
|
|
|
package auth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/zero-ppanel/zero-ppanel/apps/api/internal/svc"
|
|
"github.com/zero-ppanel/zero-ppanel/apps/api/internal/types"
|
|
"github.com/zero-ppanel/zero-ppanel/apps/rpc/core/core"
|
|
"github.com/zero-ppanel/zero-ppanel/pkg/jwtx"
|
|
"github.com/zero-ppanel/zero-ppanel/pkg/xerr"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
)
|
|
|
|
type DeviceLoginLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
// 设备登录
|
|
func NewDeviceLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeviceLoginLogic {
|
|
return &DeviceLoginLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *DeviceLoginLogic) DeviceLogin(req *types.DeviceLoginReq) (resp *types.LoginResp, err error) {
|
|
// todo: 新建设备登录是否禁用逻辑
|
|
if !l.svcCtx.Config.Device.Enable {
|
|
return nil, xerr.NewErrCode(xerr.DeviceLoginDisabled)
|
|
}
|
|
|
|
// 1. 调用 Core RPC 设备登录
|
|
rpcResp, err := l.svcCtx.CoreRpc.DeviceLogin(l.ctx, &core.DeviceLoginReq{
|
|
Identifier: req.Identifier,
|
|
UserAgent: req.UserAgent,
|
|
Ip: req.IP,
|
|
ShortCode: req.ShortCode,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 2. 检查用户是否禁用
|
|
if rpcResp.IsDisabled {
|
|
return nil, xerr.NewErrCode(xerr.UserDisabled)
|
|
}
|
|
|
|
// 3. 生成 session ID
|
|
sessionId := uuid.New().String()
|
|
|
|
// 4. 生成 JWT Token
|
|
token, err := jwtx.GenerateToken(
|
|
l.svcCtx.Config.JwtAuth.AccessSecret,
|
|
rpcResp.UserId,
|
|
"device",
|
|
rpcResp.IsAdmin,
|
|
l.svcCtx.Config.JwtAuth.AccessExpire,
|
|
)
|
|
if err != nil {
|
|
l.Errorf("GenerateToken error: %v", err)
|
|
return nil, xerr.NewErrCode(xerr.ServerError)
|
|
}
|
|
|
|
// 5. 写入 Redis session
|
|
expireDuration := time.Duration(l.svcCtx.Config.JwtAuth.AccessExpire) * time.Second
|
|
|
|
// session:{sessionId} → userId
|
|
sessionKey := fmt.Sprintf("session:%s", sessionId)
|
|
if err := l.svcCtx.Redis.SetexCtx(l.ctx, sessionKey, fmt.Sprintf("%d", rpcResp.UserId), int(expireDuration.Seconds())); err != nil {
|
|
l.Errorf("Redis set session error: %v", err)
|
|
}
|
|
|
|
// device:{identifier} → sessionId
|
|
deviceKey := fmt.Sprintf("device:%s", req.Identifier)
|
|
if err := l.svcCtx.Redis.SetexCtx(l.ctx, deviceKey, sessionId, int(expireDuration.Seconds())); err != nil {
|
|
l.Errorf("Redis set device session error: %v", err)
|
|
}
|
|
|
|
return &types.LoginResp{
|
|
Token: token,
|
|
}, nil
|
|
}
|