Two approaches of authentication have been used a lot in many books and blogs for Go:
Use http.Request
:
func getCurrentUser(r *http.Request) (*User, error) {
// get JWT token or cookie and find corresponding sessions
// and account, then return the user and nil error;
// if user is not found, return a nil user and a non-nil error
}
Then handler functions call the getCurrentUser to get the user for each request. It's possible to use a function decorator that wraps around other handlers and check the authentication before other handler functions get executed.
func secretInfoHandler (w http.ResponseWriter, r * http.Request) {
user, err := getCurrentUser(r)
if err != nil {
// write http.Unauthorized, and return
}
// otherwise, process request return data
}
func MustAuthenticate (h http.HandlerFunc) http.HandlerFunc {
return func (w http.ResponseWriter, r *http.Request) {
// chekc authentication, if pass:
h.ServeHTTP(w, r)
// if fail:
w.WriteHeader(http.StatusUnauthorized)
return
}
}
Using context.Context
:
// use the same getCurrentUser() as the one above
func MustAuthenticate (h http.HandlerFunc) http.HandlerFunc {
return func (w http.ResponseWriter, r *http.Request) {
user, err := getCurrentUser(r)
if err != nil {
// write error code then return
}
ctx := context.WithValue(r.Context(), someKey, someValue)
h(w, r.WithContext(ctx))
}
}
Then for each handler (like secretInfoHandler
), instead of calling getCurrentUser(r *http.Request)
, I just need to check if the Context
that comes with the http.Request
contains certain authenticaiton info.
They appear to be equivalent. So, what are the technical advantages/disadvantages of each approach? If they are indeed equivalent, which one is better for real-world production code to use?
Aucun commentaire:
Enregistrer un commentaire