Hoʻomohala pūnaewele pūnaewele ma Golang - mai ka maʻalahi a paʻakikī

Hoʻomohala pūnaewele pūnaewele ma Golang - mai ka maʻalahi a paʻakikī

ʻElima makahiki i hala aku nei ua hoʻomaka wau e hoʻomohala iā Gophish, hāʻawi kēia i kahi manawa e aʻo ai iā Golang. Ua ʻike au he ʻōlelo ikaika ʻo Go, i kākoʻo ʻia e nā hale waihona puke he nui. Hiki ke hoʻohana ʻia e hoʻomohala i nā noi ʻaoʻao server me ka pilikia ʻole.

ʻO kēia ʻatikala e pili ana i ke kākau ʻana i kahi kikowaena ma Go. E hoʻomaka kākou me nā mea maʻalahi e like me "Aloha honua!" a hoʻopau me kahi noi me kēia mau mana:

- Ke hoʻohana nei iā Let's Encrypt no HTTPS.
- Ke hana nei ma ke ʻano he mea hoʻokele API.
- Ke hana nei me ka middleware.
- Ka hana ʻana i nā faila static.
— Hoopau pololei.

Manaʻo ʻo Skillbox: Papa hana "Python mea hoʻomohala mai ka ʻōpala".

Hoʻomaopopo mākou iā ʻoe: no ka poʻe heluhelu a pau o "Habr" - kahi ho'ēmi o 10 rubles i ka wā e kākau inoa ai i kekahi papa Skillbox e hoʻohana ana i ka code promotional "Habr".

Aloha, honua!

Hiki iā ʻoe ke hana i kahi kikowaena pūnaewele ma Go me ka wikiwiki loa. Eia kekahi laʻana o ka hoʻohana ʻana i kahi mea hoʻohana e hoʻihoʻi i ka "Aloha, honua!" i ʻōlelo ʻia ma luna.

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

Ma hope o kēia, inā e holo ʻoe i ka noi a wehe i ka ʻaoʻao localhost, a laila e ʻike koke ʻoe i ka kikokikona "Aloha, honua!" (inā pono nā mea a pau, ʻoiaʻiʻo).

E hoʻohana mākou i ka mea lawelawe i nā manawa he nui ma hope, akā e hoʻomaopopo mua i ka hana ʻana o nā mea āpau.

net/http

Ua hoʻohana ka laʻana i ka pūʻolo net/http, ʻo ia ka mea hana mua ma Go no ka hoʻomohala ʻana i nā kikowaena ʻelua a me nā mea kūʻai aku HTTP. No ka hoʻomaopopo ʻana i ke code, e hoʻomaopopo kākou i ke ʻano o ʻekolu mea nui: http.Handler, http.ServeMux a me http.Server.

Nā mea lawelawe HTTP

Ke loaʻa iā mākou kahi noi, e kālailai ka mea lawelawe a hoʻopuka i kahi pane. Hoʻohana ʻia nā mea lawelawe ma Go penei:

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

Hoʻohana ka laʻana mua i ka hana kōkua http.HandleFunc. Hoʻopili ʻo ia i kahi hana ʻē aʻe, ʻo ia hoʻi e lawe iā http.ResponseWriter a me http.Request i ServeHTTP.

I nā huaʻōlelo ʻē aʻe, hōʻike ʻia nā mea hoʻohana ma Golang i kahi kikowaena hoʻokahi, e hāʻawi ana i nā koho he nui i ka mea papahana. No laila, no ka laʻana, hoʻokō ʻia ka middleware me ka hoʻohana ʻana i kahi mea lawelawe, kahi e hana mua ai ʻo ServeHTTP i kekahi mea a laila kāhea i ke ʻano ServeHTTP o kahi mea lawelawe ʻē aʻe.

E like me ka mea i ʻōlelo ʻia ma luna, hoʻopuka wale nā ​​mea lawelawe i nā pane i nā noi. Akā ʻo wai ka mea hoʻohana pono e hoʻohana ʻia i kekahi manawa i ka manawa?

Noi Alahele

No ka hana ʻana i ka koho kūpono, e hoʻohana i kahi HTTP multiplexer. Ua kapa ʻia ʻo muxer a i ʻole router ma kekahi mau hale waihona puke, akā like lākou a pau. ʻO ka hana o ka multiplexer ka nānā ʻana i ke ala noi a koho i ka mea lawelawe kūpono.

Inā makemake ʻoe i ke kākoʻo no ke ala paʻakikī, a laila ʻoi aku ka maikaʻi o ka hoʻohana ʻana i nā hale waihona puke ʻaoʻao ʻekolu. ʻO kekahi o nā mea kiʻekiʻe loa - gorila/mux и hele-chi/chi, hiki i kēia mau hale waihona puke ke hoʻokō i ka hana waena me ka pilikia ʻole. Me kā lākou kōkua, hiki iā ʻoe ke hoʻonohonoho i ka hoʻokele wildcard a hana i kekahi mau hana ʻē aʻe. ʻO kā lākou pōmaikaʻi ʻo ka hoʻohālikelike ʻana me nā mea lawelawe HTTP maʻamau. ʻO ka hopena, hiki iā ʻoe ke kākau i nā code maʻalahi i hiki ke hoʻololi ʻia i ka wā e hiki mai ana.

ʻO ka hana ʻana me nā ʻōhua paʻakikī i kahi kūlana maʻamau e koi i nā hoʻonā maʻamau ʻole, a paʻakikī kēia i ka hoʻohana ʻana i nā mea hoʻohana paʻamau. No ka hana ʻana i ka hapa nui o nā noi, e lawa ka hui ʻana o ka waihona paʻamau a me kahi alalai maʻalahi.

Ka Hana Ninau

Eia kekahi, pono mākou i kahi ʻāpana e "hoʻolohe" no nā pilina e komo mai a hoʻihoʻi hou i nā noi āpau i ka mea hoʻoponopono pololei. Hiki iā http.Server ke hana maʻalahi i kēia hana.

Hōʻike kēia ma lalo nei he kuleana ke kikowaena no nā hana āpau e pili ana i ka hoʻoili pili. ʻO kēia, no ka laʻana, hana me ka hoʻohana ʻana i ka protocol TLS. No ka hoʻokō ʻana i ke kelepona http.ListenAndServer, hoʻohana ʻia kahi kikowaena HTTP maʻamau.

I kēia manawa, e nānā kākou i nā laʻana paʻakikī.

Hoʻohui iā Let's Encrypt

Ma ka maʻamau, holo kā mākou noi ma luna o ka protocol HTTP, akā makemake ʻia e hoʻohana i ka protocol HTTPS. Hiki ke hana i kēia me ka pilikia ʻole ma Go. Inā loaʻa iā ʻoe kahi palapala hōʻoia a me kahi kī pilikino, a laila lawa ia e hoʻopaʻa inoa iā ListenAndServeTLS me ka palapala hōʻoia a me nā faila kī.

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

Hiki iā ʻoe ke hana maikaʻi i nā manawa a pau.

E hoʻopunipuni hāʻawi i nā palapala hōʻoia manuahi me ka hōʻano hou. No ka hoʻohana ʻana i ka lawelawe, pono ʻoe i kahi pūʻolo autocert.

ʻO ke ala maʻalahi loa e hoʻonohonoho ai ʻo ia ka hoʻohana ʻana i ke ʻano autocert.NewListener i hui pū ʻia me http.Serve. ʻAe ke ala iā ʻoe e loaʻa a hōʻano hou i nā palapala hōʻoia TLS i ka wā e noi ai ka server HTTP:

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

Inā mākou e wehe i ka polokalamu kele pūnaewele example.com, e loaʻa iā mākou kahi pane HTTPS "Aloha, honua!"

Inā makemake ʻoe i ka hoʻonohonoho kikoʻī hou aku, a laila pono ʻoe e hoʻohana i ka mana autocert.Manager. A laila hana mākou i kā mākou iho http.Server instance (a hiki i kēia manawa ua hoʻohana mākou ma ke ʻano maʻamau) a hoʻohui i ka manakia i ka server 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("", "")

He ala maʻalahi kēia e hoʻokō i ke kākoʻo HTTPS piha me ka hōʻano hou palapala hōʻoia.

Hoʻohui i nā ala maʻamau

ʻO ke alalai paʻamau i hoʻokomo ʻia i loko o ka waihona maʻamau he maikaʻi, akā he mea maʻamau. Pono ka hapa nui o nā noi i ke ala ala paʻakikī, me nā ala nested a wildcard, a i ʻole kahi kaʻina hana no ka hoʻonohonoho ʻana i nā kumu ala a me nā ʻāpana.

I kēia hihia, pono e hoʻohana i nā pūʻolo gorila/mux и hele-chi/chi. E aʻo mākou pehea e hana ai me ka mea hope - hōʻike ʻia kahi laʻana ma lalo nei.

Hāʻawi ʻia ka faila api/v1/api.go i loaʻa nā ala no kā mākou API:

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

Hoʻonoho mākou i ka prefix api/vq no nā ala i ka faila nui.

Hiki iā mākou ke kau i kēia i kā mākou mea hoʻokele nui ma lalo o ka api/v1/ prefix i kā mākou noi nui:

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

ʻO ka maʻalahi o ka hana ʻana me nā ala paʻakikī e hiki ke maʻalahi i ka hoʻonohonoho ʻana a me ka mālama ʻana i nā noi nui a paʻakikī.

Ke hana nei me ka middleware

Hoʻokomo ʻia ka hana ʻana i ka hoʻopili ʻana i kahi mea hoʻohana HTTP me kekahi, e hiki ai ke hana wikiwiki i ka hōʻoia, ka hoʻopaʻa ʻana, ka logging, a me nā hana ʻē aʻe.

E like me ka laʻana, e nānā i ka http.Handler interface; e hoʻohana mākou iā ia e kākau i kahi mea hoʻohana e hōʻoia i nā mea hoʻohana lawelawe.

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

Aia nā mea ala ala ʻekolu, e like me chi, e ʻae iā ʻoe e hoʻonui i ka hana middleware.

Ke hana nei me nā faila static

Aia i loko o ka hale waihona puke Go maʻamau ka hiki ke hana me ka ʻikepili static, me nā kiʻi, JavaScript a me nā faila CSS. Hiki ke loaʻa iā lākou ma o ka hana http.FileServer. Hoʻihoʻi ia i kahi mea lawelawe e lawelawe ana i nā faila mai kahi papa kuhikuhi kikoʻī.

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

He mea pono e hoʻomanaʻo e hōʻike ʻo http.Dir i nā mea o ka papa kuhikuhi inā ʻaʻole i loaʻa ka faila index.html nui. I kēia hihia, no ka pale ʻana i ka papa kuhikuhi mai ka compromised, pono ʻoe e hoʻohana i ka pūʻolo unindexed.

Paʻa pololei

Loaʻa iā Go kahi hiʻohiʻona i kapa ʻia ʻo ka pani ʻana o ka server HTTP. Hiki ke hana i kēia me ka hoʻohana ʻana i ke ʻano Shutdown (). Hoʻomaka ʻia ke kikowaena ma kahi goroutine, a laila hoʻolohe ʻia ke kahawai no ka loaʻa ʻana o kahi hōʻailona interrupt. I ka loaʻa ʻana o ka hōʻailona, ​​ua pio ke kikowaena, akā ʻaʻole koke, akā ma hope o kekahi mau kekona.

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)

He hopena

He ʻōlelo ikaika ʻo Go me kahi waihona maʻamau maʻamau. He ākea loa kona mau mana paʻamau, a hiki ke hoʻonui ʻia me ka hoʻohana ʻana i nā interface - hiki iā ʻoe ke hoʻomohala i nā kikowaena HTTP pono maoli.

Manaʻo ʻo Skillbox:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka