[英]GraphQL Golang Authentication with JWT
I have a GraphQL API that I've been writing in go
and wondering how to manage JWT authentication when you already are using context
to pass around data sources. I have a GraphQL API that I've been writing in
go
and wondering how to manage JWT authentication when you already are using context
to pass around data sources.
So an abbreviated version of my main
function is:所以我的
main
function 的缩写版本是:
import (
"net/http"
"github.com/graphql-go/graphql"
gqlhandler "github.com/graphql-go/handler"
)
func queryHandler(ds *sources.DataSources, gql *gqlhandler.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(context.Background(), sources.CtxSourcesKey, ds)
gql.ContextHandler(ctx, w, r)
})
}
func main() {
apiSchema, _ := schema.CompileSchema(schema.QueryType, schema.MutationType)
gql := gqlhandler.New(&gqlhandler.Config{
Schema: &apiSchema,
GraphiQL: !isDeployed,
Pretty: false,
Playground: false,
})
http.ListenAndServe(":41000", util.CreateChiRouter(healthCheckHandler(), queryHandler(ctxSources, gql)))
}
As you can see, I'm already creating a new context
instance to store and pass a map of my various data sources to the query resolution functions, but also need to be able to parse out the Authorization
header for a possible JWT to be passed down for authenticated routes.如您所见,我已经创建了一个新的
context
实例来存储并将我的各种数据源的 map 传递给查询解析函数,但还需要能够解析出Authorization
header 以将可能的 Z1D1FADBD9150349EEDZF 传递给 8150349EEDZF7 down 用于经过身份验证的路由。
What's the best way to go about this given my current situation?鉴于我目前的情况,go 的最佳方法是什么? (Combine the JWT with the data sources context? Handle data sources differently to free up
context
?) (将 JWT 与数据源上下文相结合?以不同方式处理数据源以释放
context
?)
A common way of dealing with such authentication headers is to use a middleware to deal with authentication, and add the authentication info to the current context.处理此类身份验证标头的常用方法是使用中间件来处理身份验证,并将身份验证信息添加到当前上下文中。
Currently, you're creating a new context.目前,您正在创建一个新的上下文。 I suggest using the existing HTTP context and adding to that, so you can chain things:
我建议使用现有的 HTTP 上下文并添加到其中,这样您就可以链接:
ctx := context.WithValue(r.Context(), sources.CtxSourcesKey, ds)
newReq:=r.WithContext(ctx)
gql.ContextHandler(ctx, w, newReq)
And you can install a middleware that does the same:您可以安装一个执行相同操作的中间件:
type autoInfoKeyType int
const authInfoKey authInfoKeyType=iota
func GetAuthInfo(ctx context.Context) *AuthInfo {
if v:=ctx.Value(authInfoKey); v!=nil {
return v.(*AuthInfo)
}
return nil
}
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
authInfo:=processJWT(...)
if authInfo!=nil {
ctx := context.WithValue(r.Context(), authInfoKey, authInfo)
r=r.WithContext(ctx)
}
next.ServeHTTP(w,r)
}
}
This way, you can check if the context has authentication info, and if so, use it.这样,您可以检查上下文是否具有身份验证信息,如果有,请使用它。
if authInfo:=GetAuthInfo(req.Context()); authInfo!=nil {
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.