完善认证逻辑,添加用户信息 introspect 接口,更新 .gitignore 忽略 scripts 目录

This commit is contained in:
2025-04-26 17:59:34 +08:00
parent 08c88da0ce
commit 3e837b5fec
13 changed files with 67 additions and 1378 deletions

View File

@@ -111,18 +111,24 @@ func Protect(c *fiber.Ctx, types []services.PayloadType, permissions []string) (
var auth *services.AuthContext
var err error
switch split[0] {
case "Bearer":
auth, err = authBearer(c.Context(), token)
if err != nil {
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
}
case "Basic":
if !slices.Contains(types, services.PayloadClientConfidential) {
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
}
auth, err = authBasic(c.Context(), token)
if err != nil {
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
}
default:
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
}
if err != nil {
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
}
// 检查权限

View File

@@ -11,3 +11,9 @@ type AuthForbiddenErr string
func (e AuthForbiddenErr) Error() string {
return string(e)
}
type DataErr string
func (e DataErr) Error() string {
return string(e)
}

View File

@@ -268,7 +268,7 @@ type RevokeReq struct {
}
func Revoke(c *fiber.Ctx) error {
_, err := auth.Protect(c, []s.PayloadType{s.PayloadUser}, []string{})
_, err := auth.Protect(c, []s.PayloadType{s.PayloadClientConfidential}, []string{})
if err != nil {
// 用户未登录
return nil
@@ -290,3 +290,30 @@ func Revoke(c *fiber.Ctx) error {
}
// endregion
// region /profile
type IntrospectResp struct {
m.User
}
func Introspect(c *fiber.Ctx) error {
// 验证权限
authCtx, err := auth.Protect(c, []s.PayloadType{s.PayloadUser}, []string{})
if err != nil {
return err
}
// 获取用户信息
profile, err := q.User.
Where(q.User.ID.Eq(authCtx.Payload.Id)).
Omit(q.User.Password, q.User.DeletedAt).
Take()
if err != nil {
return err
}
return c.JSON(IntrospectResp{*profile})
}
// endregion

View File

@@ -1,7 +1,6 @@
package handlers
import (
"errors"
"platform/web/auth"
q "platform/web/queries"
s "platform/web/services"
@@ -9,48 +8,8 @@ import (
"time"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
// region GetUserByToken
type GetUserByTokenReq struct {
Token string `json:"token" validate:"required"`
}
// GetUserByToken 通过token获取用户信息
func GetUserByToken(c *fiber.Ctx) error {
// 解析请求参数
req := new(GetUserByTokenReq)
if err := c.BodyParser(req); err != nil {
return err
}
// 查询会话信息
session, err := s.Session.Find(c.Context(), req.Token)
if err != nil {
return err
}
// 查询用户信息
user, err := q.User.Debug().
Omit(q.User.Password, q.User.DeletedAt).
Where(q.User.ID.Eq(session.Payload.Id)).
Take()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fiber.NewError(fiber.StatusNotFound, "用户不存在")
}
return err
}
// 返回用户信息
return c.JSON(user)
}
// endregion
// region recharge
type RechargePrepareReq struct {

View File

@@ -14,8 +14,18 @@ func ApplyRouters(app *fiber.App) {
auth := api.Group("/auth")
auth.Post("/token", handlers.Token)
auth.Post("/revoke", handlers.Revoke)
auth.Post("/introspect", handlers.Introspect)
auth.Post("/verify/sms", handlers.SmsCode)
// 用户
user := api.Group("/user")
user.Post("/identify", handlers.Identify)
user.Post("/identify/callback", handlers.IdentifyCallback)
user.Post("/recharge/prepare/alipay", handlers.RechargePrepareAlipay)
user.Post("/recharge/confirm/alipay", handlers.RechargeConfirmAlipay)
user.Post("/recharge/prepare/wechat", handlers.RechargePrepareWechat)
user.Post("/recharge/confirm/wechat", handlers.RechargeConfirmWechat)
// 通道
channel := api.Group("/channel")
channel.Post("/create", handlers.CreateChannel)
@@ -38,16 +48,6 @@ func ApplyRouters(app *fiber.App) {
resource.Post("/prepare/wechat", handlers.PrepareResourceByWechat)
resource.Post("/create/wechat", handlers.CreateResourceByWechat)
// 用户
user := api.Group("/user")
user.Post("/get/token", handlers.GetUserByToken)
user.Post("/identify", handlers.Identify)
user.Post("/identify/callback", handlers.IdentifyCallback)
user.Post("/recharge/prepare/alipay", handlers.RechargePrepareAlipay)
user.Post("/recharge/confirm/alipay", handlers.RechargeConfirmAlipay)
user.Post("/recharge/prepare/wechat", handlers.RechargePrepareWechat)
user.Post("/recharge/confirm/wechat", handlers.RechargeConfirmWechat)
// 账单
bill := api.Group("/bill")
bill.Post("/list", handlers.ListBill)

View File

@@ -134,11 +134,6 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string, confi
return err
}
// 删除旧的令牌
pipeline := tx.Pipeline()
pipeline.Del(ctx, accessKey(refreshData.AccessToken))
pipeline.Del(ctx, refreshKey(refreshToken))
// 生成新的令牌
newAccessToken := genToken()
newRefreshToken := genToken()
@@ -155,9 +150,16 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string, confi
return err
}
pipeline := tx.Pipeline()
// 保存新的令牌
pipeline.Set(ctx, accessKey(newAccessToken), authData, cfg.AccessTokenDuration)
pipeline.Set(ctx, refreshKey(newRefreshToken), newRefreshData, cfg.RefreshTokenDuration)
// 删除旧的令牌
pipeline.Del(ctx, accessKey(refreshData.AccessToken))
pipeline.Del(ctx, refreshKey(refreshToken))
_, err = pipeline.Exec(ctx)
if err != nil {
return err