103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
package auth
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"time"
|
|
|
|
"backend/app/consts"
|
|
"backend/app/http/users"
|
|
"backend/database/fields"
|
|
"backend/providers/jwt"
|
|
"backend/providers/otel"
|
|
"backend/providers/wechat"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
"github.com/pkg/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const StatePrefix = "sns_basic_auth"
|
|
|
|
// @provider
|
|
type Controller struct {
|
|
svc *Service
|
|
userSvc *users.Service
|
|
jwt *jwt.JWT
|
|
wechat *wechat.Client
|
|
log *log.Entry `inject:"false"`
|
|
}
|
|
|
|
func (ctl *Controller) Prepare() error {
|
|
ctl.log = log.WithField("module", "auth.Controller")
|
|
return nil
|
|
}
|
|
|
|
// @Router /v1/auth/wechat/jump [get]
|
|
// @Bind redirectUri query
|
|
func (ctl *Controller) JumpToAuth(ctx fiber.Ctx, tenant, redirectUri string) error {
|
|
_, span := otel.Start(ctx.Context(), "auth.controller.wechat")
|
|
defer span.End()
|
|
|
|
ctl.log.Debugf("%s, query: %v", ctx.OriginalURL(), ctx.Queries())
|
|
|
|
paramRedirect := ctx.Query("redirect")
|
|
|
|
// 添加 redirect 参数
|
|
u, err := url.Parse(string(ctx.Request().URI().FullURI()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
query := u.Query()
|
|
query.Set("redirect", paramRedirect)
|
|
u.RawQuery = query.Encode()
|
|
u.Path = "/v1/auth/wechat/login/" + tenant
|
|
fullUrl := u.String()
|
|
|
|
ctl.log.WithField("module", "middleware.SilentAuth").Debug("redirect_uri: ", fullUrl)
|
|
|
|
to, err := ctl.wechat.ScopeAuthorizeURL(
|
|
wechat.ScopeAuthorizeURLWithRedirectURI(fullUrl),
|
|
wechat.ScopeAuthorizeURLWithState(fmt.Sprintf("%s-%d", StatePrefix, time.Now().UnixNano())),
|
|
)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to get wechat auth url")
|
|
}
|
|
|
|
return ctx.Redirect().To(to.String())
|
|
}
|
|
|
|
// @Router /v1/auth/login [get]
|
|
// @Bind code query
|
|
// @Bind state query
|
|
// @Bind redirectUri query
|
|
func (ctl *Controller) Login(ctx fiber.Ctx, code, state, tenant, redirectUri string) error {
|
|
ctl.log.Debugf("code: %s, state: %s", code, state)
|
|
|
|
// get the openid
|
|
token, err := ctl.wechat.AuthorizeCode2Token(code)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to get openid")
|
|
}
|
|
ctl.log.Debugf("tokenInfo %+v", token)
|
|
|
|
userID, err := ctl.userSvc.GetUserIDByOpenID(ctx.Context(), fields.AuthChannelWeChat, token.GetOpenID())
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to get user")
|
|
}
|
|
|
|
jwtToken, err := ctl.jwt.CreateToken(ctl.jwt.CreateClaims(jwt.BaseClaims{UserID: userID}))
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create token")
|
|
}
|
|
|
|
ctx.Cookie(&fiber.Cookie{
|
|
Name: consts.TokenTypeUser.String(),
|
|
Value: jwtToken,
|
|
Expires: time.Now().Add(6 * time.Hour),
|
|
HTTPOnly: true,
|
|
})
|
|
|
|
return ctx.Redirect().To(redirectUri)
|
|
}
|