add logics

This commit is contained in:
Rogee
2024-11-29 19:23:35 +08:00
parent dd0b6dd6c1
commit 3d7ee40a7a
12 changed files with 166 additions and 49 deletions

View File

@@ -0,0 +1,136 @@
package middlewares
import (
"context"
"backend/common/consts"
"backend/modules/users"
"backend/pkg/pg"
"backend/providers/jwt"
"backend/providers/wechat"
"github.com/gofiber/fiber/v3"
"github.com/jinzhu/copier"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
// @provider
type Middlewares struct {
client *wechat.Client
userSvc *users.Service
jwt *jwt.JWT
log *log.Entry `inject:"false"`
}
func (f *Middlewares) Prepare() error {
f.log = log.WithField("module", "middleware")
return nil
}
func (f *Middlewares) Verify(c fiber.Ctx) error {
// get the query parameters
signature := c.Query("signature")
timestamp := c.Query("timestamp")
nonce := c.Query("nonce")
echostr := c.Query("echostr")
if signature == "" || timestamp == "" || nonce == "" || echostr == "" {
return c.Next()
}
log.WithField("method", "Verify").WithFields(log.Fields{
"signature": signature,
"timestamp": timestamp,
"nonce": nonce,
"echostr": echostr,
}).Debug("begin verify signature")
// verify the signature
if err := f.client.Verify(signature, timestamp, nonce); err != nil {
return c.SendString(err.Error())
}
return c.SendString(echostr)
}
func (f *Middlewares) SilentAuth(c fiber.Ctx) error {
// if cookie not exists key "openid", then redirect to the wechat auth page
tokenCookie := c.Cookies("token", "")
if tokenCookie != "" {
claim, err := f.jwt.Parse(tokenCookie)
if err != nil {
return errors.Wrap(err, "failed to parse token")
}
// query user
user, err := f.userSvc.GetByOpenID(c.Context(), claim.ID)
if err != nil {
return errors.Wrap(err, "failed to get user")
}
c.SetUserContext(context.WithValue(c.UserContext(), consts.JwtToken, tokenCookie))
c.SetUserContext(context.WithValue(c.UserContext(), consts.SessionUser, user))
return c.Next()
}
// get current full url
url := c.BaseURL()
url = "https://qvyun.mp.jdwan.com"
log.WithField("module", "middleware.SilentAuth").Debug("url:", url)
to, err := f.client.ScopeAuthorizeURL(
wechat.ScopeAuthorizeURLWithRedirectURI(url),
wechat.ScopeAuthorizeURLWithState("sns_basic_auth"),
)
if err != nil {
return errors.Wrap(err, "failed to get wechat auth url")
}
log.WithField("module", "middleware.SilentAuth").Debug("redirectTo: ", to.String())
return c.Redirect().To(to.String())
}
func (f *Middlewares) AuthUserInfo(c fiber.Ctx) error {
state := c.Query("state")
code := c.Query("code")
if state == "" && code == "" {
return c.Next()
}
if state != "sns_basic_auth" {
return c.Next()
}
log.WithField("module", "middleware.AuthUserInfo").Debug("code", code)
// get the openid
token, err := f.client.AuthorizeCode2Token(code)
if err != nil {
return errors.Wrap(err, "failed to get openid")
}
var oauthInfo pg.UserOAuth
copier.Copy(&oauthInfo, token)
user, err := f.userSvc.GetOrNew(c.Context(), token.Openid, oauthInfo)
if err != nil {
return errors.Wrap(err, "failed to get user")
}
claim := f.jwt.CreateClaims(jwt.BaseClaims{UID: uint64(user.ID)})
claim.ID = user.OpenID
jwtToken, err := f.jwt.CreateToken(claim)
if err != nil {
return errors.Wrap(err, "failed to create token")
}
// set the openid to the cookie
c.Cookie(&fiber.Cookie{
Name: "sid",
Value: jwtToken,
HTTPOnly: true,
})
return c.Redirect().To("/")
}

View File

@@ -0,0 +1,26 @@
package middlewares
import (
"backend/providers/wechat"
"git.ipao.vip/rogeecn/atom/container"
"git.ipao.vip/rogeecn/atom/utils/opt"
)
func Provide(opts ...opt.Option) error {
if err := container.Container.Provide(func(
client *wechat.Client,
) (*Middlewares, error) {
obj := &Middlewares{
client: client,
}
if err := obj.Prepare(); err != nil {
return nil, err
}
return obj, nil
}); err != nil {
return err
}
return nil
}