Skip to content

Instantly share code, notes, and snippets.

@mschoebel
Created March 6, 2014 20:02
Show Gist options
  • Save mschoebel/9398202 to your computer and use it in GitHub Desktop.
Save mschoebel/9398202 to your computer and use it in GitHub Desktop.
Snippet: login/logout (Golang)
package main
import (
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/securecookie"
"net/http"
)
// cookie handling
var cookieHandler = securecookie.New(
securecookie.GenerateRandomKey(64),
securecookie.GenerateRandomKey(32))
func getUserName(request *http.Request) (userName string) {
if cookie, err := request.Cookie("session"); err == nil {
cookieValue := make(map[string]string)
if err = cookieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
userName = cookieValue["name"]
}
}
return userName
}
func setSession(userName string, response http.ResponseWriter) {
value := map[string]string{
"name": userName,
}
if encoded, err := cookieHandler.Encode("session", value); err == nil {
cookie := &http.Cookie{
Name: "session",
Value: encoded,
Path: "/",
}
http.SetCookie(response, cookie)
}
}
func clearSession(response http.ResponseWriter) {
cookie := &http.Cookie{
Name: "session",
Value: "",
Path: "/",
MaxAge: -1,
}
http.SetCookie(response, cookie)
}
// login handler
func loginHandler(response http.ResponseWriter, request *http.Request) {
name := request.FormValue("name")
pass := request.FormValue("password")
redirectTarget := "/"
if name != "" && pass != "" {
// .. check credentials ..
setSession(name, response)
redirectTarget = "/internal"
}
http.Redirect(response, request, redirectTarget, 302)
}
// logout handler
func logoutHandler(response http.ResponseWriter, request *http.Request) {
clearSession(response)
http.Redirect(response, request, "/", 302)
}
// index page
const indexPage = `
<h1>Login</h1>
<form method="post" action="/login">
<label for="name">User name</label>
<input type="text" id="name" name="name">
<label for="password">Password</label>
<input type="password" id="password" name="password">
<button type="submit">Login</button>
</form>
`
func indexPageHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, indexPage)
}
// internal page
const internalPage = `
<h1>Internal</h1>
<hr>
<small>User: %s</small>
<form method="post" action="/logout">
<button type="submit">Logout</button>
</form>
`
func internalPageHandler(response http.ResponseWriter, request *http.Request) {
userName := getUserName(request)
if userName != "" {
fmt.Fprintf(response, internalPage, userName)
} else {
http.Redirect(response, request, "/", 302)
}
}
// server main method
var router = mux.NewRouter()
func main() {
router.HandleFunc("/", indexPageHandler)
router.HandleFunc("/internal", internalPageHandler)
router.HandleFunc("/login", loginHandler).Methods("POST")
router.HandleFunc("/logout", logoutHandler).Methods("POST")
http.Handle("/", router)
http.ListenAndServe(":8000", nil)
}
@ahmdrz
Copy link

ahmdrz commented Sep 20, 2016

Very useful. thx

@qianguozheng
Copy link

What if add an callback to check each request that want to access the path /internal in the route ?
That's would save a lot of code to check in each processing function.

@k0fi
Copy link

k0fi commented Mar 10, 2017

Awesome. Thanks.
Please make a similar jwt authentication tutorial if you can.

@therealssj
Copy link

therealssj commented Oct 4, 2017

the cookie expires everytime I restart the golang instance. any way around this?

@mschoebel
Copy link
Author

@therealssj The example generates a new secret key (lines 13 / 14) every time at startup - you have to save/read these keys from a file (for example).

Copy link

ghost commented Dec 25, 2017

Great! Awesome for there should be database integration, anyone can log with any pass!

@Maharl1kans
Copy link

Saves me time coding... I'll modify it according to my need. Thanks!

@GuilhermeVendramini
Copy link

Thanks man.

@molzieyy
Copy link

molzieyy commented Aug 6, 2018

Thanks for this

@meilier
Copy link

meilier commented Aug 24, 2018

excellent !!!

@fesenpav
Copy link

Great, thank you a lot for this.

@joseacat
Copy link

Great!

@leopedroso45
Copy link

Thanks! :)

@JSchatten
Copy link

That's saves me time coding... I'll modify it according to my need. Thank you very much!

@davidnewhall
Copy link

Beautiful. Thanks!

@wybaeb
Copy link

wybaeb commented Apr 18, 2023

Saved a lot of time, thanx!

@TorbenMartin
Copy link

so when i create a random cookie with the browser dev tools ... i am in. nice.

@mschoebel
Copy link
Author

@TorbenMartin ... if your random cookie can be successfully decoded (line 19).

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