Skip to content

router.Handle results in 404 - Assistance needed #6

@gnosthi

Description

@gnosthi

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
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions