mux
mux copied to clipboard
[bug] Headers are not accessible in Middleware when Request sent from Browser
Describe the bug
A clear and concise description of what the bug is. I am learning to add middleware in mux Router. I am getting token from request header and verifying it with hard written string. It is working fine when I send the request from Postman, but when I send the request from the web page, it never fetches the header in middleware. I have tried to send the request using all three methods fetch(), jquery ajax(), and Axios. But the result is same all the time. …
Versions
Go version: 1.19.1 package version: v1.8.0 (gorilla/mux version)
…
Steps to Reproduce
send the request from browser. I am using Google Chrome v106.0.5249.103 (Official Build) (64-bit)
…
Expected behavior
value of header sent from browser …
Code Snippets
A minimum viable code snippet can be useful! (use backticks to format it).
var userColl = make(map[string]string)
func main() {
userColl["userTokenForA"] = "a"
userColl["userTokenForB"] = "b"
handleRequests()
}
func handleRequests() {
router := mux.NewRouter().StrictSlash(true)
router.PathPrefix("/public").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("./public/"))))
router.Use(authenticate)
router.HandleFunc("/todo", db.GetAllLists).Methods("GET")
log.Fatal(http.ListenAndServe(":4010", router))
}
func authenticate(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("authentication")
user := userColl[token]
fmt.Println("token", token, "user", user)
w.Header().Set("Content-Type", "application/json")
if user != "" { //&& userColl[token] == userId {
fmt.Println("authorized...")
r.Header.Set("user", user)
next.ServeHTTP(w, r)
} else {
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode(bson.M{
"ERROR": "AUTHENTICATION FAILED",
})
}
})
}
Front End :-
(()=> {
axios("/todo", {
method: "GET",
headers: {
authentication: "userTokenForA",
"Content-Type": "application/json",
},
})
.then((res) => {
console.log("res", res)
})
.catch((err) => {
console.log("error", err)
})
})()
…
Hey @akki4vedi, I went through the given code. I found an issue in the current implementation that (though it is the correct intended behaviour) authenticate
middleware is applied on all the routes.
Technically speaking, when you're making a request to any route containing the public
prefix middleware applies and expects you to send header authentication
reason as mentioned before the middleware is applied on all the routes. If the header is missing it will return the status http.StatusUnauthorized
on the static content page.
I'm guessing this is not what you want. Just to be clear If I'm not wrong you want static routes to be served without authentication. I would highly recommend you to go through the issue https://github.com/gorilla/mux/issues/360
I tried the same and it is working fine. Attaching a screenshot for reference.
I hope this helps and solves your problem. If yes, please close this issue else I would be happy to answer your doubts/queries. Thank you 🙌🏻
Thanks for the reply. Actually, I don't want to deactivate API for any route, there is only one route in my project to test authenticate
middleware. So I am testing it and I am not able to get headers in the middleware, only when I send the request from Browser.
When I send the request from Postman, It works fine.
I can see that your middleware is perfectly working as your log msg is showing the value of userColl
. This is not happening with my code. As I mentioned in the issue, I've tried sending the request in all three ways (fetch(), jquery ajax(), and Axios).
What I have shown in the screenshot is from the browser only using the fetch
API. Just that I need to add an exception to the static
route in the middleware. As I mentioned before if you're not adding conditions for the static
route, it will require an authentication
header to be passed while making a request to the static
endpoint from the browser.
I am passing the authentication
header in the request.
But still, not able to read it in middleware.
This message is logged when I send the request from Postman.
I am not understanding why It's not working.
Hi @akki4vedi Since StrictSlash is true, this may be due to a redirect when accessing with /todo. Could you try accessing /todo/ once?
Hey @soundkitchen, I don't think it will work. I tried it and didn't get the expected output.
I'm sharing my screenshot for reference. We need to send the authentication
header when hitting the URL /public
from the browser.
In chrome browser {"ERROR":"AUTHENTICATION FAILED"}
is from the code where I have written javascript code to hit /todo/
(note the strict slash).
Chrome dev tools console shows what I'm trying to say(on how we should send requests) if we don't want to exclude /public
routes.

It doesn't matter if we're using fetch
, axios
or any other library. Middleware by definition is applied to all the routes. cc @akki4vedi
I've tried adding a slash in the route but still, it's not working. Here I'm attaching two screenshots of headers in middleware and in route,
- Headers in
authenticate
middleware - Headers in
/todo
route withoutauthenticate
middleware
@akki4vedi I wrote the code and ran it, but I was able to get the headers in Middleware.
The first screenshot you pasted doesn't seem to have a Referrer, under what circumstances was this requested? As long as the request is made from a browser using JavaScript, I would expect the Referrer to be present, but is there an exception?
I am simply calling the fetch API on load of javascript on the HTML page, the code is written in the issue as Front End. @soundkitchen & @amustaque97 Can I have code of API call in your app and the main method of the server for reference?
@akki4vedi The code I used for verification is below. I have tried to make it as similar to your code as possible. gorilla_mux_703.zip