I am really new to graphql and we are changing our old REST server to graphQL. I am trying this new custom directive but I am unable to fetch HTTP headers(as we are using multiple headers in old system) in the directive implementation or I am not aware how to that due to lack of documentation.
I should be able to get http headers value in directive/mutation/query
@rajzru I'm stuck with the same issue. @mathewbyrne Do you guys have any working examples that we can try with HTTP headers?
I have tried parsing the HTTP header and body to get header and mutation/query details in HTTP middlewares but I need to copy paste libs code and this is a redundant approach and after #221 it's very easy to implement your auth stack but unable to get headers value now.
I'll do some docs up tomorrow, graphql is transport agnostic, so we don't expose the http request. Instead you should create some http middleware that extracts what you want (the user?) From the request and adds it to context, which will then be available in your resolvers and directives
@vektah @Dipen-Dedania I have tried that and working like a charm
Authentication
Authorization
FIELD_DEFINITION and checked authorization there.Still directive is of struct type so maybe in future we can have an interface implementation there just like resolvers
@rajzru Thanks! Can you please share a sample code?
I have implemented this in the following way(pseudo code it might need few changes)
GraphQL schema
type Query {
authToDo: [ToDo!]! @isAuthenticated
}
directive @isAuthenticated on FIELD_DEFINITION
HTTP Middleware
func AuthHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dbConn := DB.Connect()
header := r.Header.Get("Authorization")
// if auth is not available then proceed to resolver
if header == "" {
next.ServeHTTP(w, r)
} else {
userData, err := Auth.VerifyIDToken(dbConn.Context, header)
if err != nil {
next.ServeHTTP(w, r)
} else {
// merge userID into request context
ctx := context.WithValue(r.Context(), "userID", userData.UID)
next.ServeHTTP(w, r.WithContext(ctx))
}
}
})
}
Directive config definition
c.Directives.IsAuthenticated = func(ctx context.Context, next graphql.Resolver) (interface{}, error) {
userID := ctx.Value("userID")
if userID != nil {
return next(ctx)
} else {
return nil, errors.New("Unauthorised")
}
}
You can edit the code as per your use case
I think I am stuck on the same issue but I am not 100% sure. If I am attempting to get a value out of the HTTP header of a GraphQL query, am I to inject this myself into the context? If so, would this be done in the server.go file? Attempting to rewrite an existing microservice with this library as a PoT for future services, but access to HTTP headers are essential. Cheers.
For those of you who are in the same boat as me and not quite sure how to implement middleware to retrieve the headers, hopefully, this article helps: https://hackernoon.com/simple-http-middleware-with-go-79a4ad62889b
Most helpful comment
I have implemented this in the following way(pseudo code it might need few changes)
GraphQL schema
HTTP Middleware
Directive config definition
You can edit the code as per your use case