HTTP Basic Auth
Go menyediakan package yang dapat digunakan untuk proses HTTP basic authentication.
Metode ini membutuhkan informasi username dan password untuk disisipkan dalam header request (dengan format tertentu) sehingga tidak memerlukan cookies maupun session. Lebih jelasnya silakan baca RFC-7617.
Data username dan password tidak langsung ditampilkan dalam header, namun data tersebut harus di-encode terlebih dahulu ke dalam format yg sudah ditentukan sesuai spesifikasi, sebelum dimasukan ke header.
Berikut adalah contoh penulisan basic auth:
// Request header
Authorization: Basic ZGF2aWR3aW5hbGRhOjEyMzQ1==
Informasi disisipkan dalam request header dengan key Authorization
dan value adalah Basic
spasi hasil enkripsi dari data username dan password. Data username dan password digabung dengan separator tanda titik dua (:
), lalu di-encode dalam format encoding Base 64.
// Username password encryption
base64encode("davidwinalda:12345")
// Hasilnya adalah ZGF2aWR3aW5hbGRhOjEyMzQ1==
Golang menyediakan fungsi untuk meng-handle request basic auth dengan cukup mudah, jadi kita tidak perlu untuk memparsing header request terlebih dahulu untuk mendapatkan informasi username dan password.
Studi Kasus
Kita akan membuat web service sederhana untuk memperlihatkan penggunaak http basic authentication.
Setup pada file main.go
main.go
Pada file main.go
, kita akan membuat fungsi main
yang berisi beberapa statement berikut:
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/student", ActionStudent)
server := new(http.Server)
server.Addr = ":8080"
fmt.Println("server started at localhost:8080")
server.ListenAndServe()
}
Pada fungsi di atas kita mendaftarkan 1 API endpoint /student
yang nantinya kita akan melakukan 2 proses GET
:
GET
/student
dimana akan menampilkan seluruh datastudents
GET
/student?id=1
dimana akan menampilkan data student berdasarkan query stringid
Lalu selanjutnya seperti yang kita lakukan sebelumnya untuk setup port dan server.
Kita akan membuat handler dari ActionStudent
masih di file main.go
yang berisi beberapa statement berikut ini:
func ActionStudent(w http.ResponseWriter, r *http.Request) {
if !Auth(w, r) {
return
}
if !AllowOnlyGET(w, r) {
return
}
if id := r.URL.Query().Get("id"); id != "" {
OutputJSON(w, GetStudentById(id))
return
}
OutputJSON(w, GetStudent())
}
Kita bisa lihat pada kode di atas bahwa ada proses pengecekan terlebih dahulu sebelum user dapat mengakses API dari /student
yaitu fungsi !Auth
. Kita juga membuat pengecekan dari !AllowOnlyGET
bahwa hanya method GET
yang bisa diproses pada endpoint ini.
Selanjutnya kita akan membuat fungsi OutputJSON
untuk encode data ke JSON:
func OutputJSON(w http.ResponseWriter, f interface{}) {
w.Header().Set("Content-Type", "application/json")
result, err := json.Marshal(f)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(result)
}
Setup pada file student.go
student.go
Pada root directory buatlah 1 file baru bernama student.go
yang masih dalam package main
. Pada file ini kita akan membuat struct
dari data students dan membuat fungsi yaitu GetStudent
dan GetStudentById
untuk nantinya dipanggil di dalam handler yang telah dibuat. Kita juga akan mengisi data secara manual pada fungsi init
package main
var students = []*Student{}
type Student struct {
Id string
Fullname string
Age int
Batch string
}
func GetStudent() []*Student {
return students
}
func GetStudentById(id string) *Student {
for _, each := range students {
if each.Id == id {
return each
}
}
return nil
}
func init() {
students = append(students, &Student{Id: "1", Fullname: "Wisma", Age: 25, Batch: "Adorable"})
students = append(students, &Student{Id: "2", Fullname: "Yudis", Age: 22, Batch: "Brilliant"})
students = append(students, &Student{Id: "3", Fullname: "Sukisno", Age: 35, Batch: "Creative"})
students = append(students, &Student{Id: "4", Fullname: "Guntur", Age: 30, Batch: "Dilligent"})
}
Setup pada file middleware.go
middleware.go
Nah inilah tahapan proses authentication. Kita akan membuat 1 file lagi pada root directory bernama middleware.go
.
Pada file ini, kita akan mendeklarasikan secara hardcode untuk data username dan password yang kita anggap telah terdaftar
const USERNAME = "davidwinalda"
const PASSWORD = "12345"
Selanjutnya kita akan membuat fungsi Auth
untuk proses pengecekan Authentication. Kita menggunakan fungsi bawaan dari package http
yaitu BasicAuth
yang akan melakukan proses decode dari header dan mengembalikan 3 data yaitu username
, password
, dan ok
. ok
akan mengembalikan status apakah request yang dilakukan valid atau tidak.
func Auth(w http.ResponseWriter, r *http.Request) bool {
username, password, ok := r.BasicAuth()
if !ok {
http.Error(w, "Something went wrong", http.StatusInternalServerError)
return false
}
isValid := (username == USERNAME) && (password == PASSWORD)
if !isValid {
http.Error(w, "Authentication is failed", http.StatusInternalServerError)
return false
}
return true
}
Jika valid maka kita bisa melakukan pengecekan untuk validasi username
dan password
:
isValid := (username == USERNAME) && (password == PASSWORD)
if !isValid {
http.Error(w, "Authentication is failed", http.StatusInternalServerError)
return false
}
Selanjutnya kita akan membuat fungsi AllowOnlyGET
untuk membatas akses endpoint hanya bisa menggunakan method GET
:
func AllowOnlyGET(w http.ResponseWriter, r *http.Request) bool {
if r.Method != "GET" {
http.Error(w, "Only allow GET method", http.StatusInternalServerError)
return false
}
return true
}
Untuk kode lengkapnya bisa dilihat di bawah ini:
package main
import "net/http"
const USERNAME = "davidwinalda"
const PASSWORD = "12345"
func Auth(w http.ResponseWriter, r *http.Request) bool {
username, password, ok := r.BasicAuth()
if !ok {
http.Error(w, "Something went wrong", http.StatusInternalServerError)
return false
}
isValid := (username == USERNAME) && (password == PASSWORD)
if !isValid {
http.Error(w, "Authentication is failed", http.StatusInternalServerError)
return false
}
return true
}
func AllowOnlyGET(w http.ResponseWriter, r *http.Request) bool {
if r.Method != "GET" {
http.Error(w, "Only allow GET method", http.StatusInternalServerError)
return false
}
return true
}
Menjalankan Program
Untuk menjalankan program kita tidak bisa menggunakan go run main.go
karena terdapat beberapa file sebagai package main
. Oleh karena itu kita dapat menjalankan program dengan perintah berikut:
go run *.go

Kita akan mencoba HTTP Authentication Basic dan mengakses API endpoint yang telah kita buat menggunakan Postman:

Jika data authentication salah atau tidak sesuai maka pada postman akan mengembalikan data berikut:

Last updated
Was this helpful?