graphql-golang
graphql-golang copied to clipboard
router.Handle results in 404 - Assistance needed
What steps did you take and what happened: Followed tutorial located here: https://www.howtographql.com/graphql-go/0-introduction/ I followed the tutorial as written and ran the application.
The application started fine, and I went to the application endpoint but got 404 not found. After some testing, I found the issue was in the Middleware (but I'm not sure where or why it isn't working) If I use http.Handle the application works as expected in that I get the playground page but I'm not able to authenticate. If I use router.Handle() I get 404 Not Found error when trying to go to the Playground page.
Working but unable to authenticate
// server.go
/*...*/
http.Handle("/", playground.Handler("GraphQL playground", "/query"))
http.Handle("/query", srv)
/*...*/
Gets 404 error when routing to the playground page
router := chi.NewRouter()
router.Use(auth.Middleware())
/*...*/
router.Handle("/", playground.Handler("GraphQL playground", "/query"))
router.Handle("/query", srv)
I even completed the tutorials coding, thinking that maybe it was an issue with where I was in the tutorial and that it would be resolved with later code. But this was not the case.
I then tested things. I am able to create a user and get a token as well as hit the 'login' endpoint using the http.Handle method but not authenticate with the "Authorization:" header. Because I cannot authenticate fully I cannot create or view links.
Below is the Middleware code. I cross-referenced it with the code in the tutorial and in this Repository.
package auth
import (
"192.168.1.215/gnosthi/graphQLTest/pkg/jwt"
"192.168.1.215/gnosthi/graphQLTest/pkg/users"
"context"
"net/http"
"strconv"
)
type contextKey struct {
name string
}
var userCtxKey = &contextKey{"user"}
func Middleware() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
header := r.Header.Get("Authorization")
// Allow unauthorized users in
if header == "" {
next.ServeHTTP(w, r)
return
}
// validate jwt token
tokenStr := header
username, err := jwt.ParseToken(tokenStr)
if err != nil {
http.Error(w, "Invalid Token", http.StatusForbidden)
return
}
// create user and check if user exists in db
user := users.User{Username: username}
id, err := users.GetUserIdByUsername(username)
if err != nil {
next.ServeHTTP(w,r)
return
}
user.ID = strconv.Itoa(id)
// put into context
ctx := context.WithValue(r.Context(), userCtxKey, &user)
r = r.WithContext(ctx)
next.ServeHTTP(w,r)
})
}
}
func ForContext(ctx context.Context) *users.User {
raw, _ := ctx.Value(userCtxKey).(*users.User)
return raw
}
What did you expect to happen: I expected to get the Playground query IDE page, be able to authenticate and create links
Anything else you would like to add: Everything appears to be working except the Middleware
Environment:
-Go Version: go version go1.17 linux/amd64
- OS: 20.04.1-Ubuntu
- Kernel-Version: 5.8.0-63-generic
- go.mod: (Direct deps only)
module 192.168.1.215/gnosthi/graphQLTest
go 1.17
require (
github.com/99designs/gqlgen v0.14.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-chi/chi v1.5.4
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-migrate/migrate v3.5.4+incompatible
github.com/vektah/gqlparser/v2 v2.2.0
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
)
Thank you I'll look into it.
Hi @gnosthi I believe the issue is with how the token is provided. I looked into the code and we do not set the auth token after the user logs in but we send the token to them so the client has to set the token otherwise the server responds with unauthenticated message