Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@ahmdrz ahmdrz commented Sep 20, 2016

Very useful. thx

@qianguozheng

This comment has been minimized.

Copy link

@qianguozheng qianguozheng commented Feb 18, 2017

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

This comment has been minimized.

Copy link

@k0fi k0fi commented Mar 10, 2017

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

@therealssj

This comment has been minimized.

Copy link

@therealssj therealssj commented Oct 4, 2017

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

@mschoebel

This comment has been minimized.

Copy link
Owner Author

@mschoebel mschoebel commented Oct 7, 2017

@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).

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Dec 25, 2017

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

@MaharlikansPH

This comment has been minimized.

Copy link

@MaharlikansPH MaharlikansPH commented Jan 23, 2018

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

@GuilhermeVendramini

This comment has been minimized.

Copy link

@GuilhermeVendramini GuilhermeVendramini commented Mar 20, 2018

Thanks man.

@molzieyy

This comment has been minimized.

Copy link

@molzieyy molzieyy commented Aug 6, 2018

Thanks for this

@meilier

This comment has been minimized.

Copy link

@meilier meilier commented Aug 24, 2018

excellent !!!

@ProfiiQus

This comment has been minimized.

Copy link

@ProfiiQus ProfiiQus commented Feb 17, 2020

Great, thank you a lot for this.

@joseacat

This comment has been minimized.

Copy link

@joseacat joseacat commented Jun 11, 2020

Great!

@leopedroso45

This comment has been minimized.

Copy link

@leopedroso45 leopedroso45 commented Jun 25, 2020

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.