使用中间件解决鉴权
This commit is contained in:
parent
b011910d20
commit
a51d39b141
@ -1,26 +1,50 @@
|
|||||||
package handle
|
package handle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
"github.com/xmdhs/authlib-skin/service"
|
||||||
|
"github.com/xmdhs/authlib-skin/service/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handel) NeedAdmin(handle http.Handler) http.Handler {
|
type tokenValue string
|
||||||
|
|
||||||
|
const tokenKey = tokenValue("token")
|
||||||
|
|
||||||
|
func (h *Handel) NeedAuth(handle http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
token := h.getTokenbyAuthorization(ctx, w, r)
|
||||||
if token == "" {
|
if token == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := h.webService.IsAdmin(ctx, token)
|
t, err := h.webService.Auth(ctx, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utilsService.ErrTokenInvalid) {
|
if errors.Is(err, utils.ErrTokenInvalid) {
|
||||||
h.handleError(ctx, w, "token 无效", model.ErrAuth, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrAuth, 401, slog.LevelDebug)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r = r.WithContext(context.WithValue(ctx, tokenKey, t))
|
||||||
|
handle.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handel) NeedAdmin(handle http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
|
err := h.webService.IsAdmin(ctx, t)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, service.ErrNotAdmin) {
|
||||||
|
h.handleError(ctx, w, err.Error(), model.ErrNotAdmin, 401, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
h.handleError(ctx, w, err.Error(), model.ErrService, 500, slog.LevelWarn)
|
||||||
|
@ -57,12 +57,8 @@ func (h *Handel) Reg() http.HandlerFunc {
|
|||||||
func (h *Handel) UserInfo() http.HandlerFunc {
|
func (h *Handel) UserInfo() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
u, err := h.webService.Info(ctx, t)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
u, err := h.webService.Info(ctx, token)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, utilsService.ErrTokenInvalid) {
|
if errors.Is(err, utilsService.ErrTokenInvalid) {
|
||||||
h.handleError(ctx, w, "token 无效", model.ErrAuth, 401, slog.LevelDebug)
|
h.handleError(ctx, w, "token 无效", model.ErrAuth, 401, slog.LevelDebug)
|
||||||
@ -81,17 +77,14 @@ func (h *Handel) UserInfo() http.HandlerFunc {
|
|||||||
func (h *Handel) ChangePasswd() http.HandlerFunc {
|
func (h *Handel) ChangePasswd() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := utils.DeCodeBody[model.ChangePasswd](r.Body, h.validate)
|
c, err := utils.DeCodeBody[model.ChangePasswd](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.webService.ChangePasswd(ctx, c, token)
|
err = h.webService.ChangePasswd(ctx, c, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrPassWord) {
|
if errors.Is(err, service.ErrPassWord) {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrPassWord, 401, slog.LevelDebug)
|
||||||
@ -110,16 +103,13 @@ func (h *Handel) ChangePasswd() http.HandlerFunc {
|
|||||||
func (h *Handel) ChangeName() http.HandlerFunc {
|
func (h *Handel) ChangeName() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
token := h.getTokenbyAuthorization(ctx, w, r)
|
t := ctx.Value(tokenKey).(*model.TokenClaims)
|
||||||
if token == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c, err := utils.DeCodeBody[model.ChangeName](r.Body, h.validate)
|
c, err := utils.DeCodeBody[model.ChangeName](r.Body, h.validate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrInput, 400, slog.LevelDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = h.webService.ChangeName(ctx, c.Name, token)
|
err = h.webService.ChangeName(ctx, c.Name, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, service.ErrExitsName) {
|
if errors.Is(err, service.ErrExitsName) {
|
||||||
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
h.handleError(ctx, w, err.Error(), model.ErrExitsName, 400, slog.LevelDebug)
|
||||||
|
@ -12,4 +12,5 @@ const (
|
|||||||
ErrAuth
|
ErrAuth
|
||||||
ErrPassWord
|
ErrPassWord
|
||||||
ErrExitsName
|
ErrExitsName
|
||||||
|
ErrNotAdmin
|
||||||
)
|
)
|
||||||
|
@ -60,14 +60,18 @@ func newSkinApi(handel *handle.Handel) http.Handler {
|
|||||||
|
|
||||||
r.Put("/user/reg", handel.Reg())
|
r.Put("/user/reg", handel.Reg())
|
||||||
r.Get("/config", handel.GetConfig())
|
r.Get("/config", handel.GetConfig())
|
||||||
r.Get("/user", handel.UserInfo())
|
|
||||||
r.Post("/user/password", handel.ChangePasswd())
|
|
||||||
r.Post("/user/name", handel.ChangeName())
|
|
||||||
|
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(handel.NeedAdmin)
|
r.Use(handel.NeedAuth)
|
||||||
r.Get("/admin/users", handel.ListUser())
|
r.Get("/user", handel.UserInfo())
|
||||||
|
r.Post("/user/password", handel.ChangePasswd())
|
||||||
|
r.Post("/user/name", handel.ChangeName())
|
||||||
|
|
||||||
|
r.Group(func(r chi.Router) {
|
||||||
|
r.Use(handel.NeedAdmin)
|
||||||
|
r.Get("/admin/users", handel.ListUser())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,15 @@ import (
|
|||||||
|
|
||||||
var ErrNotAdmin = errors.New("无权限")
|
var ErrNotAdmin = errors.New("无权限")
|
||||||
|
|
||||||
func (w *WebService) IsAdmin(ctx context.Context, token string) error {
|
func (w *WebService) Auth(ctx context.Context, token string) (*model.TokenClaims, error) {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, false)
|
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("IsAdmin: %w", err)
|
return nil, fmt.Errorf("Auth: %w", err)
|
||||||
}
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WebService) IsAdmin(ctx context.Context, t *model.TokenClaims) error {
|
||||||
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("IsAdmin: %w", err)
|
return fmt.Errorf("IsAdmin: %w", err)
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/xmdhs/authlib-skin/db/ent/user"
|
"github.com/xmdhs/authlib-skin/db/ent/user"
|
||||||
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
"github.com/xmdhs/authlib-skin/db/ent/userprofile"
|
||||||
"github.com/xmdhs/authlib-skin/model"
|
"github.com/xmdhs/authlib-skin/model"
|
||||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
|
||||||
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
utilsService "github.com/xmdhs/authlib-skin/service/utils"
|
||||||
"github.com/xmdhs/authlib-skin/utils"
|
"github.com/xmdhs/authlib-skin/utils"
|
||||||
)
|
)
|
||||||
@ -94,11 +93,7 @@ func (w *WebService) Reg(ctx context.Context, u model.User, ipPrefix, ip string)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) Info(ctx context.Context, token string) (model.UserInfo, error) {
|
func (w *WebService) Info(ctx context.Context, t *model.TokenClaims) (model.UserInfo, error) {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
|
||||||
}
|
|
||||||
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
u, err := w.client.User.Query().Where(user.ID(t.UID)).First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
return model.UserInfo{}, fmt.Errorf("Info: %w", err)
|
||||||
@ -111,11 +106,7 @@ func (w *WebService) Info(ctx context.Context, token string) (model.UserInfo, er
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, token string) error {
|
func (w *WebService) ChangePasswd(ctx context.Context, p model.ChangePasswd, t *model.TokenClaims) error {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
|
||||||
}
|
|
||||||
u, err := w.client.User.Query().Where(user.IDEQ(t.UID)).WithToken().First(ctx)
|
u, err := w.client.User.Query().Where(user.IDEQ(t.UID)).WithToken().First(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangePasswd: %w", err)
|
return fmt.Errorf("ChangePasswd: %w", err)
|
||||||
@ -160,12 +151,8 @@ func (w *WebService) changeName(ctx context.Context, newName string, uid int, uu
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WebService) ChangeName(ctx context.Context, newName string, token string) error {
|
func (w *WebService) ChangeName(ctx context.Context, newName string, t *model.TokenClaims) error {
|
||||||
t, err := utilsService.Auth(ctx, yggdrasil.ValidateToken{AccessToken: token}, w.client, w.cache, &w.prikey.PublicKey, false)
|
err := w.changeName(ctx, newName, t.UID, t.Subject)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("ChangeName: %w", err)
|
|
||||||
}
|
|
||||||
err = w.changeName(ctx, newName, t.UID, t.Subject)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ChangeName: %w", err)
|
return fmt.Errorf("ChangeName: %w", err)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user