Skip to content

Instantly share code, notes, and snippets.

@imjasonh
Created December 19, 2012 15:12
Show Gist options
  • Save imjasonh/4337383 to your computer and use it in GitHub Desktop.
Save imjasonh/4337383 to your computer and use it in GitHub Desktop.
Recipe to require that a user log in before reaching an http Handler func, without specifying it in app.yaml (similar to Python App Engine's @login_required decorator)
package mustlogin
import (
"appengine"
"appengine/user"
"fmt"
"net/http"
)
func init() {
http.HandleFunc("/1", MustLogin(loggedIn))
http.Handle("/2", MustLoginHandler{loggedIn})
}
func loggedIn(w http.ResponseWriter, r *http.Request, u user.User) {
fmt.Fprintln(w, "<html><body>")
fmt.Fprintln(w, u.Email)
url, _ := user.LogoutURL(appengine.NewContext(r), r.URL.String())
fmt.Fprintln(w, "<br /><a href=\""+url+"\">Log out</a>")
fmt.Fprintln(w, "</body></html>")
}
// Option 1: Use a closure
func MustLogin(done func(http.ResponseWriter, *http.Request, user.User)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if u := user.Current(c); u == nil {
url, _ := user.LoginURL(c, r.URL.String())
http.Redirect(w, r, url, http.StatusSeeOther)
} else {
done(w, r, *u)
}
}
}
// Option 2: Use a http.Handler
type MustLoginHandler struct {
inner func(http.ResponseWriter, *http.Request, user.User)
}
func (h MustLoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if u := user.Current(c); u == nil {
url, _ := user.LoginURL(c, r.URL.String())
http.Redirect(w, r, url, http.StatusSeeOther)
} else {
h.inner(w, r, *u)
}
}
@imjasonh
Copy link
Author

Thanks for the comments!

Re: formatting -- This appears to be a bug with Gists, it looks fine in Chrome on OSX, terrible in Chrome on Linux... I just copy/pasted this from correctly gofmt'd code :(

Re: error handling on LoginURL -- I wasn't sure how best to handle it, require the user's func to take an error as well? I wouldn't want to panic or write to the response since the downstream user might not want that...

@groks
Copy link

groks commented Dec 26, 2012

A Handler doesn't need to be a struct: https://gist.github.com/4381796

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment