Kukula kwa seva yapaintaneti ku Golang - kuchokera ku zosavuta mpaka zovuta

Kukula kwa seva yapaintaneti ku Golang - kuchokera ku zosavuta mpaka zovuta

Zaka zisanu zapitazo ndinayamba kukhazikitsa Gophish, zimenezi zinapereka mwayi wophunzira Chigolang. Ndinazindikira kuti Go ndi chinenero champhamvu, chophatikizidwa ndi malaibulale ambiri. Go ndi yosunthika: makamaka, itha kugwiritsidwa ntchito kupanga mapulogalamu am'mbali mwa seva popanda vuto lililonse.

Nkhaniyi ikunena za kulemba seva mu Go. Tiyeni tiyambe ndi zinthu zosavuta monga "Moni dziko!" ndikumaliza ndi pulogalamu yokhala ndi izi:

- Kugwiritsa Ntchito Let's Encrypt kwa HTTPS.
- Kugwira ntchito ngati rauta ya API.
- Kugwira ntchito ndi middleware.
-Kukonza mafayilo osasunthika.
- Kutseka koyenera.

Skillbox imalimbikitsa: Njira yothandiza "Wopanga python kuyambira poyambira".

Tikukukumbutsani: kwa owerenga onse a Habr - kuchotsera ma ruble 10 polembetsa maphunziro aliwonse a Skillbox pogwiritsa ntchito nambala yotsatsira ya Habr.

Moni Dziko Lapansi!

Mutha kupanga seva yapaintaneti mu Go mwachangu kwambiri. Nachi chitsanzo chogwiritsa ntchito chogwirizira chomwe chimabwezera "Moni, dziko!" Lonjezedwa pamwambapa.

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)
}

Pambuyo pake, ngati mutayendetsa pulogalamuyi ndikutsegula tsamba localhost, ndiye kuti nthawi yomweyo muwona mawu akuti "Moni, dziko!" (ngati zonse zikuyenda bwino, ndithudi).

Tidzagwiritsa ntchito kangapo pambuyo pake, koma choyamba timvetsetse momwe zonse zimagwirira ntchito.

ukonde/http

Chitsanzo chinagwiritsa ntchito phukusi net/http, ndiye chida chachikulu mu Go popanga ma seva ndi makasitomala a HTTP. Kuti timvetse code, tiyeni timvetse tanthauzo la zinthu zitatu zofunika: http.Handler, http.ServeMux ndi http.Server.

Othandizira HTTP

Tikalandira pempho, wothandizira amasanthula ndikuyankha. Ma Handlers mu Go amakhazikitsidwa motere:

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

Chitsanzo choyamba chimagwiritsa ntchito http.HandleFunc wothandizira ntchito. Ikukulunga ntchito ina, yomwe imatenga http.ResponseWriter ndi http.Request mu ServeHTTP.

Mwa kuyankhula kwina, ogwira ntchito ku Golang amawonetsedwa mu mawonekedwe amodzi, omwe amapereka zosankha zambiri kwa wopanga mapulogalamu. Kotero, mwachitsanzo, middleware ikugwiritsidwa ntchito pogwiritsa ntchito chothandizira, kumene ServeHTTP poyamba imachita chinachake ndiyeno imayitana njira ya ServeHTTP ya wothandizira wina.

Monga tafotokozera pamwambapa, othandizira amangoyankha zopempha. Koma ndi chogwirizira chiti chomwe chiyenera kugwiritsidwa ntchito panthawi inayake?

Pemphani Njira

Kuti mupange chisankho choyenera, gwiritsani ntchito HTTP multiplexer. M'malaibulale angapo amatchedwa muxer kapena rauta, koma zonse ndi zofanana. Ntchito ya multiplexer ndikusanthula njira yopempha ndikusankha chogwirizira choyenera.

Ngati mukufuna thandizo pamayendedwe ovuta, ndiye kuti ndibwino kugwiritsa ntchito malaibulale a gulu lachitatu. Zina mwazotsogola kwambiri - gorila/mux ΠΈ go-chi/chi, malaibulalewa amapangitsa kuti azitha kugwiritsa ntchito makonzedwe apakatikati popanda vuto lililonse. Ndi chithandizo chawo, mutha kukonza njira zakutchire ndikuchita ntchito zina zingapo. Ubwino wawo ndikulumikizana ndi ma HTTP okhazikika. Zotsatira zake, mukhoza kulemba code yosavuta yomwe ingasinthidwe m'tsogolomu.

Kugwira ntchito ndi ma framework ovuta muzochitika zachilendo kudzafuna njira zopanda malire, ndipo izi zimasokoneza kwambiri kugwiritsa ntchito ogwiritsira ntchito osasintha. Kuti mupange mapulogalamu ambiri, kuphatikiza laibulale yosasinthika ndi rauta yosavuta kudzakhala kokwanira.

Query Processing

Kuphatikiza apo, timafunikira gawo lomwe "limamvera" pazolumikizana zomwe zikubwera ndikulozera zopempha zonse kwa wogwirizira woyenera. http.Seva imatha kuthana ndi ntchitoyi mosavuta.

Zotsatirazi zikuwonetsa kuti seva ndiyomwe imayang'anira ntchito zonse zokhudzana ndi kukonza kulumikizana. Izi, mwachitsanzo, zimagwira ntchito pogwiritsa ntchito protocol ya TLS. Kuti mugwiritse ntchito kuyimba kwa http.ListenAndServer, seva yokhazikika ya HTTP imagwiritsidwa ntchito.

Tsopano tiyeni tione zitsanzo zovuta kwambiri.

Kuwonjezera Tiyeni Tilembetse

Mwachikhazikitso, pulogalamu yathu imayendera HTTP protocol, koma tikulimbikitsidwa kugwiritsa ntchito protocol ya HTTPS. Izi zitha kuchitika popanda mavuto mu Go. Ngati mwalandira satifiketi ndi kiyi yachinsinsi, ndiye kuti ndikwanira kulembetsa ListenAndServeTLS ndi satifiketi yolondola ndi mafayilo ofunikira.

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

Mutha kuchita bwino nthawi zonse.

Tiyeni Tilembetse imapereka satifiketi yaulere yokhala ndi kukonzanso zokha. Kuti mugwiritse ntchito ntchitoyi, muyenera phukusi autocert.

Njira yosavuta yosinthira ndiyo kugwiritsa ntchito njira ya autocert.NewListener kuphatikiza ndi http.Serve. Njirayi imakupatsani mwayi wopeza ndikusintha ziphaso za TLS pomwe seva ya HTTP ikufuna:

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

Ngati titsegula mu msakatuli chitsanzo.com, tilandira yankho la HTTPS "Moni, dziko!"

Ngati mukufuna kusinthidwa kwatsatanetsatane, muyenera kugwiritsa ntchito autocert.Manager manejala. Kenako timapanga chitsanzo chathu cha http.Server (mpaka pano tidachigwiritsa ntchito mwachisawawa) ndikuwonjezera woyang'anira ku seva ya 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("", "")

Iyi ndi njira yosavuta yopezera chithandizo chonse cha HTTPS ndikukonzanso satifiketi yokha.

Kuwonjeza njira zokhazikika

Router yokhazikika yophatikizidwa mulaibulale yokhazikika ndiyabwino, koma ndiyofunikira kwambiri. Mapulogalamu ambiri amafunikira njira zovuta kwambiri, kuphatikiza njira zachisawa ndi zakutchire, kapena njira yokhazikitsira njira ndi magawo.

Pankhaniyi ndi bwino kugwiritsa ntchito phukusi gorila/mux ΠΈ go-chi/chi. Tidzaphunzira momwe tingagwiritsire ntchito ndi omaliza - chitsanzo chikuwonetsedwa pansipa.

Fayiloyo ndi api/v1/api.go yomwe ili ndi njira za API yathu:

/ 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
}

Timayika api/vq prefix yamayendedwe mufayilo yayikulu.

Titha kuyika izi ku rauta yathu yayikulu pansi pa api/v1/ prefix mmbuyo mu pulogalamu yathu yayikulu:

// 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())

Kusavuta kwa Go pogwira ntchito ndi misewu yovuta kumapangitsa kuti zikhale zotheka kukonza ndi kukonza mapulogalamu akulu, ovuta.

Kugwira ntchito ndi middleware

Kuyika kumaphatikizapo kukulunga chogwirira chimodzi cha HTTP ndi china, kupangitsa kuti zitheke kutsimikizira, kukakamiza, kudula mitengo, ndi ntchito zina zingapo.

Mwachitsanzo, tiyeni tiwone mawonekedwe a http.Handler; tidzagwiritsa ntchito kulemba chothandizira chomwe chimatsimikizira ogwiritsa ntchito.

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)
    })
}

Pali ma routers a chipani chachitatu, monga chi, omwe amakulolani kuti muwonjezere magwiridwe antchito apakati.

Kugwira ntchito ndi static mafayilo

Laibulale yokhazikika ya Go imaphatikizapo kuthekera kogwira ntchito ndi zinthu zokhazikika, kuphatikiza zithunzi, mafayilo a JavaScript ndi CSS. Atha kupezeka kudzera mu ntchito ya http.FileServer. Imabwezera chothandizira chomwe chimatumizira mafayilo kuchokera ku bukhu linalake.

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

Ndikoyenera kukumbukira kuti http.Dir ikuwonetsa zomwe zili mu bukhuli ngati ilibe fayilo yaikulu ya index.html. Pankhaniyi, kuti chikwatu chisasokonezedwe, muyenera kugwiritsa ntchito phukusi unindexed.

Kutseka koyenera

Go ilinso ndi gawo lotchedwa kutseka kwabwino kwa seva ya HTTP. Izi zitha kuchitika pogwiritsa ntchito njira ya Shutdown(). Seva imayambika mu goroutine, ndiyeno njira imamvetsedwa kuti ilandire chizindikiro chosokoneza. Chizindikirocho chikangolandiridwa, seva imazimitsa, koma osati nthawi yomweyo, koma patatha masekondi angapo.

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)

Monga chomaliza

Go ndi chilankhulo champhamvu chokhala ndi laibulale yodziwika bwino kwambiri. Kuthekera kwake kosasinthika ndikwambiri, ndipo kumatha kukulitsidwa pogwiritsa ntchito zolumikizira - izi zimakupatsani mwayi wopanga ma seva odalirika a HTTP.

Skillbox imalimbikitsa:

Source: www.habr.com

Kuwonjezera ndemanga