Skip to content

Instantly share code, notes, and snippets.

@cpliakas
Created October 30, 2014 18:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cpliakas/0f45d0e326c47fba4e36 to your computer and use it in GitHub Desktop.
Save cpliakas/0f45d0e326c47fba4e36 to your computer and use it in GitHub Desktop.
Gorilla Mux w/ GitHub authentication
package main
import (
"flag"
"log"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/stretchr/gomniauth"
"github.com/stretchr/gomniauth/providers/github"
"github.com/stretchr/objx"
"github.com/stretchr/signature"
)
var addr = flag.String("listen", getEnv("APP_LISTEN", ":3000"), "Address:port on which to listen")
var id = flag.String("oauth-id", getEnv("APP_OAUTH_ID", "xxxx"), "OAuth ID")
var secret = flag.String("oauth-secret", getEnv("APP_OAUTH_SECRET", "xxxx"), "OAuth secret")
func main() {
flag.Parse()
gomniauth.SetSecurityKey(signature.RandomKey(64))
gomniauth.WithProviders(
github.New(*id, *secret, "http://localhost:3000/auth/callback"),
)
router := mux.NewRouter()
router.HandleFunc("/", homeCallback).Methods("GET")
router.HandleFunc("/login", loginCallback).Methods("GET")
router.HandleFunc("/auth/callback", authCallback).Methods("GET")
router.HandleFunc("/hello/{name:[a-z]+}", nameCallback).Methods("GET")
http.Handle("/", router)
log.Println("Listening on ", *addr)
http.ListenAndServe(*addr, nil)
}
// Callback for the homepage (/)
func homeCallback(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello world!"))
}
// Callback for the name (/hello/{name:[a-z]+})
func nameCallback(res http.ResponseWriter, req *http.Request) {
params := mux.Vars(req)
name := params["name"]
res.Write([]byte("Hello " + name))
}
// Login callback that auths against GitHub. See the example at
// https://github.com/stretchr/gomniauth/blob/master/example/goweb/main.go
// for the raw code this function was adapted from.
func loginCallback(res http.ResponseWriter, req *http.Request) {
provider, err := gomniauth.Provider("github")
if err != nil {
log.Println(err)
return
}
state := gomniauth.NewState("after", "success")
authUrl, err := provider.GetBeginAuthURL(state, nil)
if err != nil {
log.Println(err)
return
}
http.Redirect(res, req, authUrl, http.StatusFound)
}
// Oauth callback that GitHub redirects back to with creds. See the example at
// https://github.com/stretchr/gomniauth/blob/master/example/goweb/main.go
// for the raw code this function was adapted from.
func authCallback(res http.ResponseWriter, req *http.Request) {
provider, err := gomniauth.Provider("github")
if err != nil {
log.Println(err)
return
}
m := make(objx.Map)
for k, vs := range req.URL.Query() {
m.Set(k, vs)
}
creds, err := provider.CompleteAuth(m)
if err != nil {
log.Println(err)
return
}
// load the user
_, err := provider.GetUser(creds)
if userErr != nil {
log.Println(err)
return
}
res.Write([]byte("OK"))
}
// Helper function that reads an environment variable and
// returns a default value if the variable isn't set.
func getEnv(env string, def string) string {
val := os.Getenv(env)
if len(val) != 0 {
return val
} else {
return def
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment