Sunday 1 November 2020

go webapp 15 bcrypt password

 
register new user, user is saved on server memory, and browser cookie for testing

//cmd - print hashed password
C:\Users\bob\golang1>go run tutorial.go
current registration
username:  bob
hashed password:  [36 50 97 36 49 48 36 78 105 122 75 74 87 69 73 114 84 86 119 86 73 48 55 52 51 117 114 121 79 55 102 76 77 111 77 65 69 101 84 88 115 52 89 103 49 47 89 97 65 115 83 98 75 98 72 121 48 86 46 67]

                                           
redirected to login page, retrieve user from cookie, password is hashed by bcrypt

login -> server compare user entry with user on server memory with bcrypt
if they are different, login fail

                                          
if match is found, login successful

//tutorial.go

package main

import (
//"fmt"
"fmt"
"html/template"
"net/http"

"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"golang.org/x/crypto/bcrypt"
)

type car struct {
Color   string
Mileage int
Model   string
}

type auth struct {
Username string
Password []byte
Status   string
}

var templates *template.Template
var store = sessions.NewCookieStore([]byte("secret"))
var testUsername = ""
var testPassword = []byte("")


var truck = car{
Color:   "black",
Mileage: 12345,
Model:   "F-150",
}

var sedan = car{
Color:   "white",
Mileage: 321,
Model:   "Corolla",
}

func indexGetHandler(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "index.html", []car{truck, sedan})
}


func loginGetHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
registeredUser, _ := session.Values["username"]
registeredHashedPassword, _ := session.Values["hashedPassword"]

templates.ExecuteTemplate(w, "login.html",
auth{Password: registeredHashedPassword.([]byte), Username: registeredUser.(string)})
}

func loginPostHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
err := bcrypt.CompareHashAndPassword(testPassword, []byte(password))

if err != nil || username != testUsername {
templates.ExecuteTemplate(w, "login.html",
auth{Password: testPassword, Username: testUsername, Status: "failed"})
} else {
templates.ExecuteTemplate(w, "login.html",
auth{Password: testPassword, Username: testUsername, Status: "succcess"})
}
}

func registerGetHandler(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "register.html", nil)
}

func registerPostHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")

cost := bcrypt.DefaultCost
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), cost)
if err != nil {
return
}
testUsername = username
testPassword = hashedPassword
fmt.Println("current registration")
fmt.Println("username: ", username)
fmt.Println("hashed password: ", hashedPassword)

session, _ := store.Get(r, "session")
session.Values["username"] = username
session.Values["hashedPassword"] = hashedPassword
session.Save(r, w)

http.Redirect(w, r, "/login", 302)
}

func main() {
templates = template.Must(template.ParseGlob("templates/*.html"))
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
//r.HandleFunc("/", indexPostHandler).Methods("POST")
r.HandleFunc("/login", loginGetHandler).Methods("GET")
r.HandleFunc("/login", loginPostHandler).Methods("POST")
r.HandleFunc("/register", registerGetHandler).Methods("GET")
r.HandleFunc("/register", registerPostHandler).Methods("POST")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8000", nil)
}

-----------------------------------------
//login.html
<html>

<head>
    <title>Login</title>
</head>

<body>
    <form method="POST">
        <div> Username: <input name="username"></div><br />
        <div></div>Password: <input name="password"></div><br />
        <div> <a href="/register">create new account</a></div><br /><br />
        <div> <button type="submit">Login</button></div>
    </form>
    <div>authentication status: {{.Status}}</div><br />
    <div>current registered user</div>
    <div>username: {{.Username}}</div>
    <div>password: {{.Password}}</div>
</body>

</html>

--------------------------------------------
//register.html
<html>

<head>
    <title>Register</title>
</head>

<body>
    <form method="POST">
        <div> Username: <input name="username"></div><br />
        <div></div>Password: <input name="password"></div><br /><br />
        <div> <button type="submit">Register</button></div><br />
    </form>
</body>

</html>

reference:

go session

go template

No comments:

Post a Comment