Files
quyun/backend/app/http/auth.go
2025-04-15 21:20:04 +08:00

113 lines
2.6 KiB
Go

package http
import (
"fmt"
"net/url"
"time"
"quyun/app/models"
"quyun/database/fields"
"quyun/database/schemas/public/model"
"quyun/providers/jwt"
"quyun/providers/wechat"
"github.com/go-jet/jet/v2/qrm"
"github.com/gofiber/fiber/v3"
gonanoid "github.com/matoous/go-nanoid/v2"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
const (
StatePrefix = "sns_basic_auth"
salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
// @provider
type auth struct {
wechat *wechat.Client
jwt *jwt.JWT
}
// @Router /auth/login [get]
// @Bind code query
// @Bind state query
// @Bind redirect query
func (ctl *auth) Login(ctx fiber.Ctx, code, state, redirect string) error {
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")
}
log.Debugf("tokenInfo %+v", token)
authUserInfo, err := ctl.wechat.AuthorizeUserInfo(token.AccessToken, token.Openid)
if err != nil {
return errors.Wrap(err, "failed to get user info")
}
log.Debugf("Auth User Info: %+v", authUserInfo)
user, err := models.Users.GetUserByOpenID(ctx.Context(), token.Openid)
if err != nil {
if errors.Is(err, qrm.ErrNoRows) {
// Create User
model := &model.Users{
Status: fields.UserStatusOk,
OpenID: token.GetOpenID(),
Username: fmt.Sprintf("u_%s", gonanoid.MustGenerate(salt, 8)),
Avatar: nil,
}
if err := models.Users.Create(ctx.Context(), model); err != nil {
return errors.Wrap(err, "failed to create user")
}
} else {
return errors.Wrap(err, "failed to get user")
}
}
jwtToken, err := ctl.jwt.CreateToken(ctl.jwt.CreateClaims(jwt.BaseClaims{UserID: user.ID}))
if err != nil {
return errors.Wrap(err, "failed to create token")
}
ctx.Cookie(&fiber.Cookie{
Name: "token",
Value: jwtToken,
Expires: time.Now().Add(6 * time.Hour),
HTTPOnly: true,
})
return ctx.Redirect().To(redirect)
}
// @Router /auth/wechat [get]
// @Bind redirect query
func (ctl *auth) Wechat(ctx fiber.Ctx, redirect string) error {
log.Debugf("%s, query: %v", ctx.OriginalURL(), ctx.Queries())
// 添加 redirect 参数
u, err := url.Parse(string(ctx.Request().URI().FullURI()))
if err != nil {
return err
}
query := u.Query()
query.Set("redirect", redirect)
u.RawQuery = query.Encode()
u.Path = "/auth/login"
fullUrl := u.String()
log.Debug("redirect_uri: ", fullUrl)
to, err := ctl.wechat.ScopeAuthorizeURL(
wechat.ScopeAuthorizeURLWithRedirectURI(fullUrl),
)
if err != nil {
return errors.Wrap(err, "failed to get wechat auth url")
}
return ctx.Redirect().To(to.String())
}