如何在http.Request中使用golang 1.7 context(用于身份验证)

时间:2016-10-23 05:31:26

标签: go

我有一个IsAuthenticated函数来检查请求是否经过身份验证(检查Authorization标题中的JWT)

func IsAuthenticated(a *framework.AppContext, r *http.Request) (int, error) {
  // ... do authentication. user is authenticated User object
  ctx := context.WithValue(r.Context(), "user", user)
  r = r.WithContext(ctx) 
  return 200, nil
} 

我发现r = r.WithContext(ctx)似乎没有覆盖请求对象?我该如何实现呢?我需要重新订购请求吗?

1 个答案:

答案 0 :(得分:7)

我不清楚你所展示的是什么是“中间件”,或者它是如何被执行的。由于您只是更改了本地变量r,并且从未将其提供给其他任何人,因此您的更改无法在您的函数之外显示。

go go版本中有各种各样的中间件风格,但自从1.7以来我看到了更多的中间件功能:

func IsAuthenticated(next http.Handler) http.Handler{
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
       //authenticate. Set cookies.
       //403 if not authenticated, etc.
       ctx := context.WithValue(r.Context(), "user",u)
       next(w,r.WithContext(ctx))
    })
}

这可以用来像这样链接处理程序:

http.Handle("/foo/bar", IsAuthenticated(myHandler))

(或使用alice之类的东西来使链接中间件变得更加容易。)

这样,当myHandler被调用时,它将由IsAuthenticated创建新请求,并且可以通过以下内容获取用户:

user := r.Context().Get("user").(*User)