首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gqlgen从解析程序设置cookie

gqlgen从解析程序设置cookie
EN

Stack Overflow用户
提问于 2021-02-08 01:08:42
回答 1查看 530关注 0票数 0

我用的是杜松子酒和gqlgen。我需要从解析器设置cookie,但我的解析器中只有上下文和来自graphQL的输入。这个问题已经在github中得到了回答。但这一次不同,因为当你尝试传入ctx.Next时,我不能改变ctx.Writer.Write和任何东西。因为gin不是那样工作的。

代码语言:javascript
复制
func (r *mutationResolver) Login(ctx context.Context, email string, password string) (bool, error) {
        // You need ctx.Writer to set a cookie and can't access that from here
}

我已经解决了这个问题,下面我想回答我自己的问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-08 01:08:42

middleware中,您必须构建一个结构对象,将ctx.Writer传入其中,将一个指针设置为ctx.Request.Context,并设置一个方法来为您设置cookie。

代码语言:javascript
复制
type CookieAccess struct {
    Writer     http.ResponseWriter
    UserId     uint64
    IsLoggedIn bool
}
// method to write cookie
func (this *CookieAccess) SetToken(token string) {
    http.SetCookie(this.Writer, &http.Cookie{
        Name:     cookieName,
        Value:    token,
        HttpOnly: true,
        Path:     "/",
        Expires:  time.Now().Add(token_expire),
    })
}

在你的middleware

代码语言:javascript
复制
func extractUserId(ctx *gin.Context) (uint64, error) {
    c, err := ctx.Request.Cookie(cookieName)
    if err != nil {
        return 0, errors.New("There is no token in cookies")
    }

    userId, err := ParseToken(c.Value)
    if err != nil {
        return 0, err
    }
    return userId, nil
}

func setValInCtx(ctx *gin.Context, val interface{}) {
    newCtx := context.WithValue(ctx.Request.Context(), cookieAccessKeyCtx, val)
    ctx.Request = ctx.Request.WithContext(newCtx)
}

func Middleware() gin.HandlerFunc {
    return func(ctx *gin.Context) {
        cookieA := CookieAccess{
            Writer: ctx.Writer,
        }

        // &cookieA is a pointer so any changes in future is changing cookieA is context
        setValInCtx(ctx, &cookieA)

        userId, err := extractUserId(ctx)
        if err != nil {
            cookieA.IsLoggedIn = false
            ctx.Next()
            return
        }

        cookieA.UserId = userId
        cookieA.IsLoggedIn = true

       // calling the actual resolver
        ctx.Next()
       // here will execute after resolver and all other middlewares was called
       // so &cookieA is safe from garbage collector
    }
}

你必须在你的解析器中调用这个函数。它获取ctx并返回&cookieA

代码语言:javascript
复制
func GetCookieAccess(ctx context.Context) *CookieAccess {
    return ctx.Value(cookieAccessKeyCtx).(*CookieAccess)
}

最后,在你的Login解析器中:

代码语言:javascript
复制
CA := security.GetCookieAccess(ctx)
CA.SetToken(token)
CA.UserId = userId

我希望这能帮助到某些人:))

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66090686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档