完善认证逻辑,添加用户信息 introspect 接口,更新 .gitignore 忽略 scripts 目录
This commit is contained in:
@@ -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, "没有权限")
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user