You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.4 KiB
Go

package auth
import (
"context"
"git.noahlan.cn/n-admin/n-admin-server/api/internal/svc"
"git.noahlan.cn/n-admin/n-admin-server/api/internal/types"
"git.noahlan.cn/n-admin/n-admin-server/dal"
"git.noahlan.cn/n-admin/n-admin-server/dal/errx"
"git.noahlan.cn/n-admin/n-admin-server/rpc/core/types/core"
"git.noahlan.cn/noahlan/ntool-biz/core/jwt"
"git.noahlan.cn/noahlan/ntool-biz/core/nstatus"
"git.noahlan.cn/noahlan/ntool/ndef"
"git.noahlan.cn/noahlan/ntool/nlog"
"net/http"
"strings"
)
// login 登录
func login(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request, user *core.UserInfo) (*types.LoginResp, error) {
defer func() {
if err := loginRecord(ctx, svcCtx, r, user.ID); err != nil {
nlog.Errorw("记录登录次数失败", nlog.Field("err", err))
}
}()
rolesBuilder := new(strings.Builder)
for i, v := range user.Roles {
rolesBuilder.WriteString(v.Code)
if i != len(user.Roles)-1 {
rolesBuilder.WriteString(ndef.CommaStr)
}
}
// TODO 检测账号1是否开启两步验证(已配置) 2是否需要两步验证(异地登录之类)
// 生成 token
token, err := jwt.NewJwtToken(
svcCtx.Config.Auth.AccessSecret,
user.ID,
svcCtx.Config.Auth.AccessExpire,
jwt.WithRandID(),
jwt.WithOption(jwt.KeyRoles, rolesBuilder.String()),
)
if err != nil {
return nil, nstatus.NewBizErrWithCode(errx.JwtTokenGenerateErr)
}
// TODO 落地Token
return &types.LoginResp{
TwoFactorType: "",
Token: types.LoginTokenInfo{
UID: user.ID,
TokenType: "Bearer",
AccessToken: token.AccessToken,
ExpiresAt: token.ExpiresAt,
Scope: "",
},
}, nil
}
// loginRecord 记录登录
func loginRecord(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request, uid int64) error {
// 记录登录次数
_, err := svcCtx.CoreRpc.Record(ctx, &core.LoginRecordInfo{
UserId: uid,
LastLoginIpv4: r.RemoteAddr,
LastLoginDevice: r.Header.Get(dal.UserDeviceKey),
LastLoginUa: r.UserAgent(),
})
if err != nil {
return err
}
return nil
}
// register 注册用户
func register(ctx context.Context, svcCtx *svc.ServiceContext, user *core.UserInfo) (*core.UserInfo, error) {
// 自动注册
rpcResp, err := svcCtx.CoreRpc.CreateUser(ctx, user)
if err != nil {
return nil, err
}
dbData, err := svcCtx.CoreRpc.GetUser(ctx, &core.UserReq{
ID: rpcResp.ID,
})
if err != nil {
return nil, err
}
return dbData, nil
}