samedi 7 juillet 2018

Authentication using request vs context

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