diff --git a/backend/app/http/wechats.go b/backend/app/http/wechats.go index 6a5f3ab..2caee0f 100644 --- a/backend/app/http/wechats.go +++ b/backend/app/http/wechats.go @@ -1,10 +1,14 @@ package http import ( + "time" + + "quyun/app/models" "quyun/database/schemas/public/model" "quyun/providers/wechat" "github.com/gofiber/fiber/v3" + "github.com/gofiber/fiber/v3/log" ) // @provider @@ -17,5 +21,31 @@ type wechats struct { // @Bind url query // @Bind user local func (ctl *wechats) GetJsSDK(ctx fiber.Ctx, url string, user *model.Users) (*wechat.JsSDK, error) { + if user.AuthToken.Data.StableExpiresAt.After(time.Now()) { + token, err := ctl.wechat.RefreshAccessToken(user.AuthToken.Data.RefreshToken) + if err != nil { + return nil, err + } + log.Infof("refresh token: %+v", token) + + stableToken, err := ctl.wechat.GetStableAccessToken() + if err != nil { + return nil, err + } + user.AuthToken.Data.StableAccessToken = stableToken.AccessToken + + oldToken := user.AuthToken.Data + oldToken.AccessToken = token.AccessToken + oldToken.ExpiresAt = time.Now().Add(time.Second * time.Duration(token.ExpiresIn)) + + oldToken.StableAccessToken = stableToken.AccessToken + oldToken.StableExpiresAt = time.Now().Add(time.Second * time.Duration(stableToken.ExpiresIn)) + + if err := models.Users.UpdateUserToken(ctx.Context(), user.ID, oldToken); err != nil { + return nil, err + } + user.AuthToken.Data = oldToken + } + return ctl.wechat.GetJsSDK(user.AuthToken.Data.StableAccessToken, url) } diff --git a/backend/app/middlewares/mid_auth.go b/backend/app/middlewares/mid_auth.go index b157f07..ef38b58 100644 --- a/backend/app/middlewares/mid_auth.go +++ b/backend/app/middlewares/mid_auth.go @@ -3,6 +3,7 @@ package middlewares import ( "net/url" "strings" + "time" "quyun/app/models" "quyun/pkg/utils" @@ -70,6 +71,17 @@ func (f *Middlewares) Auth(ctx fiber.Ctx) error { } return ctx.Redirect().To(fullUrl) } + + // TOKEN 过期 + if user.AuthToken.Data.ExpiresAt.Before(time.Now()) { + // remove cookie + ctx.ClearCookie("token") + if ctx.XHR() { + return ctx.SendStatus(fiber.StatusUnauthorized) + } + return ctx.Redirect().To(fullUrl) + } + ctx.Locals("user", user) return ctx.Next() diff --git a/backend/app/models/users.go b/backend/app/models/users.go index 70b36d2..149feb7 100644 --- a/backend/app/models/users.go +++ b/backend/app/models/users.go @@ -5,6 +5,7 @@ import ( "time" "quyun/app/requests" + "quyun/database/fields" "quyun/database/schemas/public/model" "quyun/database/schemas/public/table" @@ -385,3 +386,21 @@ func (m *usersModel) UpdateUsername(ctx context.Context, id int64, username stri } return nil } + +// UpdateUserToken +func (m *usersModel) UpdateUserToken(ctx context.Context, id int64, token fields.UserAuthToken) error { + tbl := table.Users + stmt := tbl. + UPDATE(tbl.AuthToken). + SET(fields.ToJson(token)). + WHERE( + tbl.ID.EQ(Int64(id)), + ) + m.log.Infof("sql: %s", stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log.Errorf("error updating user token: %v", err) + return err + } + return nil +} diff --git a/backend/providers/wechat/response.go b/backend/providers/wechat/response.go index c6d6036..225b37d 100644 --- a/backend/providers/wechat/response.go +++ b/backend/providers/wechat/response.go @@ -11,6 +11,7 @@ func (r *ErrorResponse) Error() error { type AccessTokenResponse struct { ErrorResponse - AccessToken string `json:"access_token,omitempty"` - ExpiresIn int `json:"expires_in,omitempty"` // seconds + AccessToken string `json:"access_token,omitempty"` + RefreshToken string `json:"refresh_token,omitempty"` + ExpiresIn int `json:"expires_in,omitempty"` // seconds } diff --git a/backend/providers/wechat/wechat.go b/backend/providers/wechat/wechat.go index 95c4d07..0fc874f 100644 --- a/backend/providers/wechat/wechat.go +++ b/backend/providers/wechat/wechat.go @@ -89,6 +89,26 @@ func (we *Client) wrapParams(params map[string]string) map[string]string { return params } +// RefreshAccessToken +func (we *Client) RefreshAccessToken(refreshToken string) (*AccessTokenResponse, error) { + params := we.wrapParams(map[string]string{ + "grant_type": "refresh_token", + "refresh_token": refreshToken, + }) + + var data AccessTokenResponse + _, err := we.client.R().SetSuccessResult(&data).SetQueryParams(params).Get("/sns/oauth2/refresh_token") + if err != nil { + return nil, errors.Wrap(err, "call /sns/oauth2/refresh_token failed") + } + + if data.ErrCode != 0 { + return nil, data.Error() + } + + return &data, nil +} + func (we *Client) GetAccessToken() (*AccessTokenResponse, error) { params := map[string]string{ "grant_type": "client_credential", diff --git a/frontend/wechat/src/hooks/useWxSDK.js b/frontend/wechat/src/hooks/useWxSDK.js index 48551ea..fa724a3 100644 --- a/frontend/wechat/src/hooks/useWxSDK.js +++ b/frontend/wechat/src/hooks/useWxSDK.js @@ -16,8 +16,8 @@ export function useWxSDK() { "chooseImage", "uploadImage", "previewImage", - "onMenuShareTimeline", - "onMenuShareAppMessage", + "updateAppMessageShareData", + "updateAppMessageShareData", "chooseWXPay", ], openTagList: [], @@ -35,20 +35,23 @@ export function useWxSDK() { onSuccess = () => { }, onCancel = () => { } ) { - wx.onMenuShareTimeline({ + console.log("setShareInfo called", shareInfo); + wx.updateTimelineShareData({ title: shareInfo.title, // 分享标题 link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: shareInfo.imgUrl, success: function () { + console.log("分享朋友圈成功", e); // 用户确认分享后执行的回调函数 onSuccess(); }, cancel: function () { + console.log("分享朋友圈取消", e); onCancel(); // 用户取消分享后执行的回调函数 }, }); - wx.onMenuShareAppMessage({ + wx.updateAppMessageShareData({ title: shareInfo.title, // 分享标题 desc: shareInfo.desc, link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 @@ -56,13 +59,13 @@ export function useWxSDK() { type: "link", // 分享类型,music、video或link,不填默认为link success: function (e) { // 用户确认分享后执行的回调函数 - onSuccess(); console.log("分享成功", e); + onSuccess(); }, cancel: function (e) { // 用户取消分享后执行的回调函数 - onCancel(); console.log("分享取消", e); + onCancel(); }, }); } diff --git a/frontend/wechat/src/views/ArticleDetail.vue b/frontend/wechat/src/views/ArticleDetail.vue index f1085e6..5b70c23 100644 --- a/frontend/wechat/src/views/ArticleDetail.vue +++ b/frontend/wechat/src/views/ArticleDetail.vue @@ -1,131 +1,159 @@ @@ -194,4 +221,4 @@ onUnmounted(() => { width: 100%; max-height: 100vh; } - \ No newline at end of file + diff --git a/frontend/wechat/vite.config.js b/frontend/wechat/vite.config.js index edd0f67..524d0f5 100644 --- a/frontend/wechat/vite.config.js +++ b/frontend/wechat/vite.config.js @@ -18,6 +18,7 @@ export default defineConfig({ server: { port: 3000, open: true, + allowedHosts: [".jdwan.com", "0.0.0.0", "127.0.0.1", "localhost", "10.1.1.108"], proxy: { '/v1': 'http://localhost:8088', }