Skip to content

Commit

Permalink
对接用户多 APP 登录
Browse files Browse the repository at this point in the history
  • Loading branch information
flycash committed Jul 27, 2024
1 parent 4e8c696 commit 2ea31ea
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 26 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,10 @@
- credit - 10
- project - 11
- marketing - 12
- roadmap - 13 # 路线图
- roadmap - 13 # 路线图

## 内部 APP ID
因为整个后台会被用于所有的 APP(我们会有很多 AI 应用)

- 0 或者不存在:八股文网站本体
- 1:AI 雅思
31 changes: 31 additions & 0 deletions internal/pkg/ectx/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2023 ecodeclub
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ectx

import (
"context"
)

const (
appCtxKey = "app"
)

// AppFromCtx 这个只会检测 app 本身,并不会从 uid 里面推测
// 如果不存在,就返回0,表示这个是 webook 本体
func AppFromCtx(ctx context.Context) (uint, bool) {
app := ctx.Value(appCtxKey)
val, ok := app.(uint)
return val, ok
}
2 changes: 1 addition & 1 deletion internal/pkg/middleware/check_appid_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type CheckAppIdBuilder struct {
}

const (
appIDHeader = "app"
appIDHeader = "X-APP"
AppCtxKey = "app"
)

Expand Down
12 changes: 6 additions & 6 deletions internal/user/internal/integration/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ type HandleTestSuite struct {
}

func (s *HandleTestSuite) SetupSuite() {
econf.Set("http_users", map[string]any{})
s.db = testioc.InitDB()
err := dao.InitTables(s.db)
require.NoError(s.T(), err)
Expand Down Expand Up @@ -543,7 +542,6 @@ type HandlerWithAppTestSuite struct {
}

func (s *HandlerWithAppTestSuite) SetupSuite() {
econf.Set("http_users", map[string]any{})
s.db = testioc.InitDB()
econf.Set("server", map[string]any{"debug": true})
server := egin.Load("server").Build()
Expand Down Expand Up @@ -577,6 +575,8 @@ func (s *HandlerWithAppTestSuite) SetupSuite() {
}))
})

server.Use(middleware.NewCheckAppIdBuilder().Build())

hdl.PrivateRoutes(server.Engine)
hdl.PublicRoutes(server.Engine)
s.server = server
Expand Down Expand Up @@ -675,7 +675,7 @@ func (s *HandlerWithAppTestSuite) TestEditProfile() {
req, err := http.NewRequest(http.MethodPost,
"/users/profile", iox.NewJSONReader(tc.req))
req.Header.Set("content-type", "application/json")
req.Header.Set("app", fmt.Sprintf("%d", tc.app))
req.Header.Set("X-APP", fmt.Sprintf("%d", tc.app))
require.NoError(t, err)
recorder := test.NewJSONResponseRecorder[any]()
s.server.ServeHTTP(recorder, req)
Expand Down Expand Up @@ -926,7 +926,7 @@ func (s *HandlerWithAppTestSuite) TestVerify() {
req, err := http.NewRequest(http.MethodPost,
"/oauth2/wechat/callback", iox.NewJSONReader(tc.req))
req.Header.Set("content-type", "application/json")
req.Header.Set("app", fmt.Sprintf("%d", tc.app))
req.Header.Set("X-APP", fmt.Sprintf("%d", tc.app))
require.NoError(t, err)
recorder := test.NewJSONResponseRecorder[web.Profile]()
s.server.ServeHTTP(recorder, req)
Expand Down Expand Up @@ -1074,7 +1074,7 @@ func (s *HandlerWithAppTestSuite) TestMiniVerify() {
req, err := http.NewRequest(http.MethodPost,
"/oauth2/wechat/mini/callback", iox.NewJSONReader(tc.req))
req.Header.Set("content-type", "application/json")
req.Header.Set("app", fmt.Sprintf("%d", tc.appid))
req.Header.Set("X-APP", fmt.Sprintf("%d", tc.appid))
require.NoError(t, err)
recorder := test.NewJSONResponseRecorder[web.Profile]()
s.server.ServeHTTP(recorder, req)
Expand Down Expand Up @@ -1133,7 +1133,7 @@ func (s *HandlerWithAppTestSuite) TestProfile() {
req, err := http.NewRequest(http.MethodGet,
"/users/profile", nil)
req.Header.Set("content-type", "application/json")
req.Header.Set("app", fmt.Sprintf("%d", tc.appid))
req.Header.Set("X-APP", fmt.Sprintf("%d", tc.appid))
require.NoError(t, err)
recorder := test.NewJSONResponseRecorder[web.Profile]()
s.server.ServeHTTP(recorder, req)
Expand Down
16 changes: 6 additions & 10 deletions internal/user/internal/repository/dao/user_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"

"github.com/ecodeclub/webook/internal/pkg/ectx"

"github.com/ecodeclub/webook/internal/pkg/snowflake"
"github.com/gotomicro/ego/core/elog"
"github.com/pkg/errors"
Expand Down Expand Up @@ -44,8 +46,8 @@ func (u *UserInsertCallBackBuilder) Build() func(db *gorm.DB) {
return func(db *gorm.DB) {
table := db.Statement.Table
if table == UserTableName {
appid, ok := appId(db.Statement.Context)
// 没设置就是默认的webook的appid
appid, ok := ectx.AppFromCtx(db.Statement.Context)
// 没设置就是默认的 webook 的appid
if !ok {
appid = WebookApp
}
Expand Down Expand Up @@ -74,7 +76,7 @@ func (u *UserInsertCallBackBuilder) Build() func(db *gorm.DB) {
}
}

// 除insert以外的语句
// UserCallBackBuilder 除insert以外的语句
type UserCallBackBuilder struct {
logger *elog.Component
}
Expand All @@ -93,7 +95,7 @@ func (u *UserCallBackBuilder) Build() func(db *gorm.DB) {

func build(db *gorm.DB, logger *elog.Component) {
ctx := db.Statement.Context
appid, ok := appId(ctx)
appid, ok := ectx.AppFromCtx(ctx)
var tableName string
var err error
if ok {
Expand Down Expand Up @@ -135,12 +137,6 @@ func userId(ctx context.Context) (int64, bool) {
return uid, ok
}

func appId(ctx context.Context) (uint, bool) {
val := ctx.Value(appCtxKey)
appid, ok := val.(uint)
return appid, ok
}

func tableNameFromAppId(appid uint) (string, error) {
// 如果是0是webook不用加后缀
if appid == 0 {
Expand Down
7 changes: 4 additions & 3 deletions internal/user/internal/repository/dao/user_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ func (u *UserPlugin) Initialize(db *gorm.DB) error {
if err != nil {
panic(err)
}
err = db.Callback().Query().Before("*").Register("user_query", NewUserCallBackBuilder().Build())
shardingByApp := NewUserCallBackBuilder().Build()
err = db.Callback().Query().Before("*").Register("user_query", shardingByApp)
if err != nil {
return err
}
err = db.Callback().Delete().Before("*").Register("user_delete", NewUserCallBackBuilder().Build())
err = db.Callback().Delete().Before("*").Register("user_delete", shardingByApp)
if err != nil {
return err
}
err = db.Callback().Create().Before("*").Register("user_create", insertBuilder.Build())
if err != nil {
return err
}
return db.Callback().Update().Before("*").Register("user_update", NewUserCallBackBuilder().Build())
return db.Callback().Update().Before("*").Register("user_update", shardingByApp)
}
8 changes: 6 additions & 2 deletions internal/user/internal/service/wechat_web_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"net/url"
"time"

"github.com/ecodeclub/webook/internal/pkg/ectx"

"github.com/ecodeclub/ecache"
"github.com/ecodeclub/ekit/net/httpx"
"github.com/ecodeclub/webook/internal/user/internal/domain"
Expand Down Expand Up @@ -46,7 +48,7 @@ type WechatWebOAuth2Service struct {
func NewWechatService(cache ecache.Cache, appId, appSecret, redirectURL string) OAuth2Service {
return &WechatWebOAuth2Service{
cache: cache,
redirectURL: url.PathEscape(redirectURL),
redirectURL: redirectURL,
logger: elog.DefaultLogger,
client: http.DefaultClient,
appId: appId,
Expand All @@ -55,7 +57,9 @@ func NewWechatService(cache ecache.Cache, appId, appSecret, redirectURL string)
}

func (s *WechatWebOAuth2Service) AuthURL(ctx context.Context, a AuthParams) (string, error) {
return fmt.Sprintf(authURLPattern, s.appId, s.redirectURL, s.getState(ctx, a)), nil
internalApp, _ := ectx.AppFromCtx(ctx)
redirectURL := fmt.Sprintf(s.redirectURL, internalApp)
return fmt.Sprintf(authURLPattern, s.appId, url.PathEscape(redirectURL), s.getState(ctx, a)), nil
}

func (s *WechatWebOAuth2Service) getState(ctx context.Context, a AuthParams) string {
Expand Down
4 changes: 2 additions & 2 deletions internal/user/internal/web/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ func NewHandler(

func (h *Handler) PrivateRoutes(server *gin.Engine) {
users := server.Group("/users")
users.GET("/profile", middleware.NewCheckAppIdBuilder().Build(), ginx.S(h.Profile))
users.POST("/profile", middleware.NewCheckAppIdBuilder().Build(), ginx.BS[EditReq](h.Edit))
users.GET("/profile", ginx.S(h.Profile))
users.POST("/profile", ginx.BS[EditReq](h.Edit))
}

func (h *Handler) PublicRoutes(server *gin.Engine) {
Expand Down
7 changes: 6 additions & 1 deletion ioc/gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ func initGinxServer(sp session.Provider,
res.Use(cors.New(cors.Config{
ExposeHeaders: []string{"X-Refresh-Token", "X-Access-Token"},
AllowCredentials: true,
AllowHeaders: []string{"X-Timestamp", "Authorization", "Content-Type"},
AllowHeaders: []string{"X-Timestamp",
"X-APP",
"Authorization", "Content-Type"},
AllowOriginFunc: func(origin string) bool {
if strings.HasPrefix(origin, "http://localhost") {
return true
Expand All @@ -99,6 +101,9 @@ func initGinxServer(sp session.Provider,
ctx.String(http.StatusOK, "hello, world!")
})

// 放到这里统一管理,后续扩展性更加好
res.Use(middleware.NewCheckAppIdBuilder().Build())

// 微信支付的回调不需要安全校验机制
paymentHdl.PublicRoutes(res.Engine)

Expand Down

0 comments on commit 2ea31ea

Please sign in to comment.