Golang ရှိ ဝဘ်ဆာဗာ ဖွံ့ဖြိုးတိုးတက်မှု - ရိုးရှင်းမှ ရှုပ်ထွေးသည်။

Golang ရှိ ဝဘ်ဆာဗာ ဖွံ့ဖြိုးတိုးတက်မှု - ရိုးရှင်းမှ ရှုပ်ထွေးသည်။

လွန်ခဲ့တဲ့ ငါးနှစ်လောက်က စခဲ့တယ်။ Gophish ကို ဖွံ့ဖြိုးတိုးတက်အောင်လုပ်ပါ။၊ ဒါက Golang ကိုလေ့လာဖို့အခွင့်အရေးတစ်ခုပေးတယ်။ Go သည် စာကြည့်တိုက်များစွာဖြင့် ဖြည့်စွက်ထားသော အစွမ်းထက်သောဘာသာစကားတစ်ခုဖြစ်ကြောင်း ကျွန်တော်နားလည်ခဲ့သည်။ Go သည် စွယ်စုံရဖြစ်သည်- အထူးသဖြင့်၊ ၎င်းကို ပြဿနာမရှိဘဲ ဆာဗာဘက်ရှိ အပလီကေးရှင်းများ ဖန်တီးရန်အတွက် အသုံးပြုနိုင်သည်။

ဤဆောင်းပါးသည် Go တွင်ဆာဗာတစ်ခုရေးသားခြင်းအကြောင်းဖြစ်သည်။ "Hello world!" ကဲ့သို့သော ရိုးရှင်းသောအရာများဖြင့် စတင်ပြီး အောက်ပါစွမ်းရည်များဖြင့် အပလီကေးရှင်းတစ်ခုဖြင့် အဆုံးသတ်ကြပါစို့။

- HTTPS အတွက် Let's Encrypt ကို အသုံးပြုခြင်း။
- API Router အဖြစ် အလုပ်လုပ်ခြင်း။
- အလယ်တန်းဆော့ဖ်ဝဲဖြင့် အလုပ်လုပ်ခြင်း။
- static ဖိုင်များကိုလုပ်ဆောင်ခြင်း။
- မှန်ကန်သောပိတ်ခြင်း။

Skillbox မှ အကြံပြုထားသည်- လက်တွေ့သင်တန်း "Python developer သည် အစမှနေ၍".

ငါတို့မင်းကိုသတိပေးတယ် "Habr" ၏စာဖတ်သူအားလုံးအတွက် - "Habr" ပရိုမိုးရှင်းကုဒ်ကို အသုံးပြု၍ မည်သည့် Skillbox သင်တန်းတွင်စာရင်းသွင်းသည့်အခါ 10 ရူဘယ်လျှော့စျေး။

မင်္ဂလာပါကမ္ဘာလောက!

Go တွင် ဝဘ်ဆာဗာတစ်ခုကို သင်ဖန်တီးနိုင်သည်။ ဤသည်မှာ အထက်ဖော်ပြပါ ကတိပြုထားသည့် “Hello, world!” ကို ပြန်ပေးသည့် handler ကိုအသုံးပြုခြင်း၏ ဥပမာတစ်ခုဖြစ်သည်။

package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.ListenAndServe(":80", nil)
}

ပြီးသွားရင်တော့ application ကို run ပြီး page ကိုဖွင့်လိုက်ပါ။ localhostဒါဆိုရင် "Hello, world!" ဆိုတဲ့ စာသားကို ချက်ချင်းမြင်ရပါလိမ့်မယ်။ (အရာအားလုံး မှန်ကန်ရင် ဟုတ်ပါတယ်)။

ကျွန်ုပ်တို့သည် နောက်ပိုင်းတွင် ကိုင်တွယ်ကိရိယာကို အကြိမ်များစွာ အသုံးပြုပါမည်၊ သို့သော် အရာအားလုံး မည်သို့အလုပ်လုပ်သည်ကို ဦးစွာနားလည်ကြပါစို့။

net/http

ဥပမာက package ကိုသုံးတယ်။ net/httpဆာဗာများနှင့် HTTP ဖောက်သည်များ နှစ်မျိုးလုံးကို ဖော်ဆောင်ရန်အတွက် Go တွင် အဓိကကိရိယာဖြစ်သည်။ ကုဒ်ကိုနားလည်ရန်၊ http.Handler၊ http.ServeMux နှင့် http.Server ဟူသော အရေးကြီးသောဒြပ်စင်သုံးခု၏ အဓိပ္ပါယ်ကို နားလည်ကြပါစို့။

HTTP ကိုင်တွယ်သူများ

ကျွန်ုပ်တို့ တောင်းဆိုချက်ကို လက်ခံရရှိသောအခါ၊ ကိုင်တွယ်သူသည် ၎င်းကို ပိုင်းခြားစိတ်ဖြာပြီး တုံ့ပြန်မှုကို ထုတ်ပေးပါသည်။ Go in Handlers များကို အောက်ပါအတိုင်း အကောင်အထည်ဖော်သည်-

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

ပထမဥပမာတွင် http.HandleFunc helper function ကိုအသုံးပြုသည်။ ၎င်းသည် http.ResponseWriter နှင့် http.Request ကို ServeHTTP သို့ ယူဆောင်သွားသည့် အခြားသောလုပ်ဆောင်ချက်ကို ခြုံငုံမိပါသည်။

တစ်နည်းဆိုရသော်၊ Golang ရှိ handlers များကို ပရိုဂရမ်မာအတွက် ရွေးချယ်စရာများစွာပေးသည့် တစ်ခုတည်းသော မျက်နှာပြင်တစ်ခုတွင် ပြသထားသည်။ ထို့ကြောင့်၊ ဥပမာအားဖြင့်၊ ServeHTTP တစ်ခုခုကို ဦးစွာလုပ်ဆောင်ပြီး အခြားကိုင်တွယ်သူ၏ ServeHTTP နည်းလမ်းကို ခေါ်သည့် ကိုင်တွယ်ကိရိယာကို အသုံးပြု၍ အလယ်တန်းဆော့ဖ်ဝဲကို အကောင်အထည်ဖော်သည်။

အထက်တွင်ဖော်ပြခဲ့သည့်အတိုင်း၊ ကိုင်တွယ်သူများသည် တောင်းဆိုချက်များကို တုံ့ပြန်မှုများကို ရိုးရှင်းစွာထုတ်ပေးပါသည်။ သို့သော် အချိန်ကာလတစ်ခုတွင် မည်သည့်လက်ကိုင်ကိရိယာကို အသုံးပြုသင့်သနည်း။

လမ်းကြောင်းတောင်းဆိုခြင်း။

မှန်ကန်သောရွေးချယ်မှုပြုလုပ်ရန် HTTP multiplexer ကို အသုံးပြုပါ။ စာကြည့်တိုက်များစွာတွင် ၎င်းကို muxer သို့မဟုတ် router ဟုခေါ်တွင်သော်လည်း ၎င်းတို့အားလုံးသည် အတူတူပင်ဖြစ်သည်။ multiplexer ၏လုပ်ဆောင်ချက်မှာ တောင်းဆိုမှုလမ်းကြောင်းကိုခွဲခြမ်းစိတ်ဖြာပြီး သင့်လျော်သောကိုင်တွယ်သူကိုရွေးချယ်ရန်ဖြစ်သည်။

အကယ်၍ သင်သည် ရှုပ်ထွေးသောလမ်းကြောင်းတင်ခြင်းအတွက် ပံ့ပိုးမှုလိုအပ်ပါက၊ ပြင်ပအဖွဲ့အစည်းစာကြည့်တိုက်များကို အသုံးပြုခြင်းသည် ပိုကောင်းပါသည်။ အချို့သော အဆင့်မြင့်ဆုံး- ဂေါ်ရီလာ/မက်စ် и Go-chi/chiဤစာကြည့်တိုက်များသည် ပြဿနာတစ်စုံတစ်ရာမရှိဘဲ အလယ်အလတ်လုပ်ဆောင်ခြင်းကို အကောင်အထည်ဖော်နိုင်စေသည်။ ၎င်းတို့၏အကူအညီဖြင့်၊ သင်သည် wildcard လမ်းကြောင်းသတ်မှတ်ခြင်းကို သတ်မှတ်နိုင်ပြီး အခြားလုပ်ဆောင်စရာများစွာကို လုပ်ဆောင်နိုင်သည်။ ၎င်းတို့၏အားသာချက်မှာ စံ HTTP ကိုင်တွယ်သူများနှင့် လိုက်ဖက်ညီမှုဖြစ်သည်။ ရလဒ်အနေဖြင့်၊ သင်သည် အနာဂတ်တွင် ပြုပြင်နိုင်သော ရိုးရှင်းသောကုဒ်ကို ရေးသားနိုင်သည်။

ပုံမှန်အခြေအနေတစ်ခုတွင် ရှုပ်ထွေးသောဘောင်များနှင့်အတူ အလုပ်လုပ်ခြင်းသည် စံမဟုတ်သောဖြေရှင်းနည်းများ လိုအပ်မည်ဖြစ်ပြီး ၎င်းသည် ပုံသေကိုင်တွယ်သူအသုံးပြုမှုကို သိသိသာသာရှုပ်ထွေးစေသည်။ အပလီကေးရှင်း အများစုကို ဖန်တီးရန်၊ ပုံသေစာကြည့်တိုက်နှင့် ရိုးရိုး router ပေါင်းစပ်မှု လုံလောက်မည်ဖြစ်သည်။

မေးမြန်းမှု လုပ်ဆောင်ခြင်း။

ထို့အပြင်၊ အဝင်ချိတ်ဆက်မှုများအတွက် "နားဆင်" မည့် အစိတ်အပိုင်းတစ်ခု လိုအပ်ပြီး တောင်းဆိုချက်အားလုံးကို မှန်ကန်သော ကိုင်တွယ်သူထံ ပြန်ညွှန်းပေးမည့် အစိတ်အပိုင်းတစ်ခု လိုအပ်ပါသည်။ http.Server သည် ဤလုပ်ငန်းကို အလွယ်တကူ ကိုင်တွယ်နိုင်သည်။

ချိတ်ဆက်မှု လုပ်ဆောင်ခြင်းနှင့် ဆက်စပ်သည့် အလုပ်အားလုံးအတွက် ဆာဗာသည် တာဝန်ရှိကြောင်း အောက်ပါတို့က ပြသသည်။ ဥပမာ၊ ၎င်းသည် TLS ပရိုတိုကောကို အသုံးပြု၍ အလုပ်လုပ်သည်။ http.ListenAndServer ခေါ်ဆိုမှုကို အကောင်အထည်ဖော်ရန်၊ ပုံမှန် HTTP ဆာဗာကို အသုံးပြုသည်။

ယခု ပိုမိုရှုပ်ထွေးသော ဥပမာများကို ကြည့်ကြပါစို့။

စာဝှက်ထည့်ကြပါစို့

မူရင်းအားဖြင့်၊ ကျွန်ုပ်တို့၏ အပလီကေးရှင်းသည် HTTP ပရိုတိုကောကို ကျော်၍ လုပ်ဆောင်သော်လည်း HTTPS ပရိုတိုကောကို အသုံးပြုရန် အကြံပြုထားသည်။ Go တွင် ပြဿနာမရှိဘဲ ၎င်းကို လုပ်ဆောင်နိုင်သည်။ အကယ်၍ သင်သည် လက်မှတ်နှင့် သီးသန့်သော့ကို လက်ခံရရှိပါက၊ မှန်ကန်သော လက်မှတ်နှင့် သော့ဖိုင်များဖြင့် ListenAndServeTLS ကို စာရင်းသွင်းရန် လုံလောက်ပါသည်။

http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)

အမြဲတမ်း ပိုကောင်းအောင်လုပ်နိုင်တယ်။

စေမယ့်စာဝှက် အလိုအလျောက်သက်တမ်းတိုးခြင်းဖြင့် အခမဲ့လက်မှတ်များကို ပေးသည်။ ဝန်ဆောင်မှုကိုအသုံးပြုရန်အတွက် ပက်ကေ့ခ်ျတစ်ခု လိုအပ်ပါသည်။ autocert.

၎င်းကို configure လုပ်ရန် အလွယ်ကူဆုံးနည်းလမ်းမှာ http.Serve နှင့် ပေါင်းစပ်ထားသော autocert.NewListener နည်းလမ်းကို အသုံးပြုခြင်းဖြစ်သည်။ HTTP ဆာဗာမှ တောင်းဆိုမှုများကို လုပ်ဆောင်နေချိန်တွင် နည်းလမ်းသည် သင့်အား TLS လက်မှတ်များကို ရယူပြီး အပ်ဒိတ်လုပ်ရန် ခွင့်ပြုသည်-

http.Serve(autocert.NewListener("example.com"), nil)

ဘရောက်ဆာမှာ ဖွင့်လိုက်ရင် example.comHTTPS တုံ့ပြန်မှု "မင်္ဂလာပါ ကမ္ဘာ!"

သင်ပိုမိုအသေးစိတ်ဖွဲ့စည်းပုံလိုအပ်ပါက၊ autocert.Manager မန်နေဂျာကို အသုံးပြုသင့်သည်။ ထို့နောက် ကျွန်ုပ်တို့သည် ကျွန်ုပ်တို့၏ကိုယ်ပိုင် http.Server instance ကိုဖန်တီးပြီး (ယခုကျွန်ုပ်တို့မူလအားဖြင့် ၎င်းကိုအသုံးပြုခဲ့သည်) နှင့် မန်နေဂျာကို TLSConfig ဆာဗာသို့ ထည့်ပါ-

m := &autocert.Manager{
Cache:      autocert.DirCache("golang-autocert"),
Prompt:     autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org", "www.example.org"),
}
server := &http.Server{
    Addr:      ":443",
    TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")

၎င်းသည် အလိုအလျောက် လက်မှတ် သက်တမ်းတိုးခြင်းဖြင့် HTTPS ပံ့ပိုးမှု အပြည့်အစုံကို အကောင်အထည်ဖော်ရန် လွယ်ကူသော နည်းလမ်းဖြစ်သည်။

စိတ်ကြိုက်လမ်းကြောင်းများထည့်ခြင်း။

စံစာကြည့်တိုက်တွင် ပါဝင်သော မူရင်း router သည် ကောင်းမွန်သော်လည်း ၎င်းသည် အလွန်အခြေခံသည်။ အပလီကေးရှင်းအများစုသည် nested နှင့် wildcard လမ်းကြောင်းများ အပါအဝင် ပိုမိုရှုပ်ထွေးသောလမ်းကြောင်းများ လိုအပ်သည် သို့မဟုတ် လမ်းကြောင်းပုံစံများနှင့် ကန့်သတ်ချက်များကို သတ်မှတ်ရန်အတွက် လုပ်ထုံးလုပ်နည်းတစ်ခု လိုအပ်ပါသည်။

ဤကိစ္စတွင်၎င်းသည် packages များကိုအသုံးပြုရကျိုးနပ်သည်။ ဂေါ်ရီလာ/မက်စ် и Go-chi/chi. ကျွန်ုပ်တို့သည် နောက်ပိုင်းတွင် မည်သို့လုပ်ဆောင်ရမည်ကို လေ့လာပါမည် - ဥပမာတစ်ခုကို အောက်တွင် ပြထားသည်။

ကျွန်ုပ်တို့၏ API အတွက် လမ်းကြောင်းများပါရှိသော api/v1/api.go ဖိုင်ကို ပေးထားပါသည်။

/ HelloResponse is the JSON representation for a customized message
type HelloResponse struct {
Message string `json:"message"`
}
 
// HelloName returns a personalized JSON message
func HelloName(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
response := HelloResponse{
Message: fmt.Sprintf("Hello %s!", name),
}
jsonResponse(w, response, http.StatusOK)
}
 
// NewRouter returns an HTTP handler that implements the routes for the API
func NewRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{name}", HelloName)
return r
}

ကျွန်ုပ်တို့သည် ပင်မဖိုင်ရှိ လမ်းကြောင်းများအတွက် api/vq ရှေ့ဆက်ကို သတ်မှတ်ပေးသည်။

ထို့နောက် ကျွန်ုပ်တို့သည် ကျွန်ုပ်တို့၏ပင်မအပလီကေးရှင်းတွင် api/v1/ prefix အောက်ရှိ ကျွန်ုပ်တို့၏ပင်မ router သို့ တပ်ဆင်နိုင်သည်-

// NewRouter returns a new HTTP handler that implements the main server routes
func NewRouter() http.Handler {
router := chi.NewRouter()
    router.Mount("/api/v1/", v1.NewRouter())
    return router
}
http.Serve(autocert.NewListener("example.com"), NewRouter())

Go ၏ရှုပ်ထွေးသောလမ်းကြောင်းများနှင့်အလုပ်လုပ်ရလွယ်ကူခြင်းသည်ကြီးမားပြီးရှုပ်ထွေးသောအသုံးချပရိုဂရမ်များ၏ဖွဲ့စည်းပုံနှင့်ထိန်းသိမ်းမှုကိုရိုးရှင်းလွယ်ကူစေသည်။

အလယ်တန်းဆော့ဖ်ဝဲဖြင့် အလုပ်လုပ်သည်။

Staging တွင် HTTP handler တစ်လုံးကို အခြားတစ်ခုနှင့် ပတ်ထားခြင်းဖြင့် authentication၊ compression၊ logging နှင့် အခြားသော function အများအပြားကို လျင်မြန်စွာ လုပ်ဆောင်နိုင်စေပါသည်။

ဥပမာအနေနဲ့၊ http.Handler အင်တာဖေ့စ်ကို ကြည့်ရအောင်၊ ဝန်ဆောင်မှုအသုံးပြုသူတွေကို စစ်မှန်ကြောင်းအထောက်အထားပြတဲ့ လက်ကိုင်ကိုရေးဖို့ အသုံးပြုပါမယ်။

func RequireAuthentication(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !isAuthenticated(r) {
            http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
            return
        }
        // Assuming authentication passed, run the original handler
        next.ServeHTTP(w, r)
    })
}

အလယ်တန်းဆော့ဖ်ဝဲလုပ်ဆောင်နိုင်စွမ်းကို တိုးချဲ့ခွင့်ပြုသည့် Chi ကဲ့သို့သော ပြင်ပအဖွဲ့အစည်းရောက်တာများရှိသည်။

static ဖိုင်များနှင့်အလုပ်လုပ်ခြင်း။

Go စံပြစာကြည့်တိုက်တွင် ပုံများ၊ JavaScript နှင့် CSS ဖိုင်များအပါအဝင် တည်ငြိမ်သောအကြောင်းအရာဖြင့် လုပ်ဆောင်နိုင်သော စွမ်းရည်များ ပါဝင်သည်။ ၎င်းတို့ကို http.FileServer လုပ်ဆောင်ချက်ဖြင့် ဝင်ရောက်ကြည့်ရှုနိုင်ပါသည်။ ၎င်းသည် သီးခြားလမ်းညွှန်တစ်ခုမှ ဖိုင်များကို ဆောင်ရွက်ပေးသည့် ကိုင်တွယ်သူကို ပြန်ပေးသည်။

func NewRouter() http.Handler {
    router := chi.NewRouter()
    r.Get("/{name}", HelloName)
 
// Настройка раздачи статических файлов
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
    router.Handle("/*", fs)
    
    return r

http.Dir သည် ပင်မ index.html ဖိုင်မပါဝင်ပါက လမ်းညွှန်၏ အကြောင်းအရာများကို ပြသမည်မှာ သေချာပါသည်။ ဤကိစ္စတွင်၊ လမ်းညွှန်ကိုအခိုးခံရခြင်းမှကာကွယ်ရန်၊ သင်အထုပ်ကိုအသုံးပြုသင့်သည်။ unindexed.

မှန်ကန်သောပိတ်ခြင်း။

Go တွင် HTTP ဆာဗာကို သပ်ရပ်စွာပိတ်ခြင်းဟုခေါ်သည့် အင်္ဂါရပ်တစ်ခုလည်း ပါရှိသည်။ Shutdown() method ကို အသုံးပြု၍ လုပ်ဆောင်နိုင်ပါသည်။ ဆာဗာကို ဂိုရိုးတင်းပုံစံဖြင့် စတင်ထားပြီး၊ ထို့နောက်တွင် ကြားဖြတ်အချက်ပြမှုကို လက်ခံရရှိရန် ချန်နယ်ကို နားထောင်သည်။ အချက်ပြခြင်းကို လက်ခံရရှိသည်နှင့် တပြိုင်နက် ဆာဗာသည် ပိတ်သွားသော်လည်း ချက်ချင်းမဟုတ်သော်လည်း စက္ကန့်အနည်းငယ်ကြာပြီးနောက်၊

handler := server.NewRouter()
srv := &http.Server{
    Handler: handler,
}
 
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
 
// Wait for an interrupt
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
 
// Attempt a graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)

နိဂုံးချုပ်

Go သည် စကြဝဠာ စံပြစာကြည့်တိုက်ပါရှိသော အားကောင်းမောင်းသန်ဘာသာစကားတစ်ခုဖြစ်သည်။ ၎င်း၏မူလစွမ်းရည်များသည် အလွန်ကျယ်ပြန့်ပြီး ၎င်းတို့ကို အင်တာဖေ့စ်များအသုံးပြု၍ မြှင့်တင်နိုင်သည် - ၎င်းသည် သင့်အား အမှန်တကယ်ယုံကြည်စိတ်ချရသော HTTP ဆာဗာများကို တီထွင်နိုင်စေမည်ဖြစ်သည်။

Skillbox မှ အကြံပြုထားသည်-

source: www.habr.com

DDoS ကာကွယ်ရေး၊ VPS VDS ဆာဗာများပါသည့် ဆိုက်များအတွက် ယုံကြည်စိတ်ချရသော hosting ကို ဝယ်ယူပါ။ 🔥 DDoS ကာကွယ်မှု၊ VPS VDS ဆာဗာများပါရှိသော ယုံကြည်စိတ်ချရသော ဝဘ်ဆိုက် hosting ကို ဝယ်ယူပါ | ProHoster