Package webtools is a collection of helper functions, types, and abstractions for building standalone websites. In particular, sites that make use of oauth based sessions for user identity and authentication.
The webtools packages can be added to a Go project with go get.
go get cattlecloud.net/go/webtools@latestimport "cattlecloud.net/go/webtools"For setting common headers with correct values on http.ResponseWriter objects,
including:
Content-Type
webtools.SetContentType(w, webtools.ContentTypeRSS)X-Robots-Tag
webtools.SetRobotsTag(w, webtools.RobotsYesIndex)Cache-Control
webtools.SetCacheControl(w, 24 * time.Hour)Authorization
webtools.SetBasicAuth(w, "admin", "passw0rd")Also helps with crafting net/url.URL values with correctly encoded URL
paramter values.
u := webtools.CreateURL("example.org", "/some/path", map[string]string {
"token": "abc123",
"page": "2",
})There is also the Origins convenience function for parsing the user-agent
of an http.Request and creating a struct of interesting values regarding the
request.
ua := webtools.Origins(r)
fmt.Println(ua.String()) # e.g. curl/unknown
fmt.Println(ua.Anchor()) # e.g. example.org/path/to/page
fmt.Println(ua.From()) # e.g. 10.0.0.1Provides utilities for building HTMX-compatible responses. The package includes an Interface for rendering HTMX responses, along with support for plain text, raw HTML, and templated content.
type Interface interface {
Write(io.Writer) error
}htmx.Write(
w, // any io.Writer; typically http.ResponseWriter
htmx.Text{Content: "Hello, World!"},
)//go:embed templates/*
var templates embed.FS
tmplFS := htmx.FS(templates, "templates")
http.HandleFunc("GET /partial", func(w http.ResponseWriter, r *http.Request) {
htmx.Write(w, &htmx.Template{
FS: tmplFS,
Filename: "button.html",
Fields: data,
})
})Use Component for rendering raw HTML templates defined inline:
html := `<button hx-post="/click">{{ .Count }} clicks</button>`
htmx.Write(w, &htmx.Component{
HTML: html,
Fields: struct{ Count int }{Count: 42},
})Use SetRedirect instead of http.Redirect when handling HTMX requests to perform a client-side redirect:
func handler(w http.ResponseWriter, r *http.Request) {
htmx.SetRedirect(w, "/new-page")
}Use SetNoSwap to keep existing content in place after a HTMX transition. Useful for setting error messages on forms:
func errorHandler(w http.ResponseWriter, err error) {
htmx.SetNoSwap(w)
htmx.Write(w, htmx.Text{Content: err.Error()})
}Provides a generic sessions http.Handler which can be used to set and validate
user sessions. The primary interface is (optionally) implemented by using the
oauth and identity packages in this module.
type Sessions[I identity.UserIdentity] interface {
Create(I, time.Duration) *http.Cookie
Match(I, *conceal.Text) error
}Provides a sharable http.Client that sets sensible values for maintaining a
pool of idle connections.
client := httpclient.Get()Provides a set of generic structs used for marshaling identity. The interfaces
are (optionally) implemented by using the oauth and identity packages in
this module.
type UserIdentity any
type UserData[I UserIdentity] interface {
Identity() I
Token() *conceal.Text
}
type UserSession[I UserIdentity] interface {
Identity() I
Active() bool
}Provides implementations for cookie creation, session management, and TTL
enabled session token caching. Intended to be used as the implementation details
of the middles and identity packages, and by using the nonces, applekeys,
googlekeys, and microsoftkeys packages as OAuth provider token validators.
Provides an implementation to manage nonce values used during the OAuth token
exchange. The primary interface enables you to Create a nonce, and then
Consume the nonce exactly once.
type Mint interface {
Create() *conceal.Text
Consume(*conceal.Text) error
}Provides an interface and implementation for validation JWT token claims as issued by Apple.
type Validator interface {
Validate(string) (*Claims, error)
}Provides an interface and implementation for validation JWT token claims as issued by Google.
type Validator interface {
Validate(string) (*Claims, error)
}Provides an interface and implementation for validation JWT token claims as issued by Microsoft.
type Validator interface {
Validate(string) (*Claims, error)
}The implementation details of what belongs in your http.Handler are currently
not a part of this suite of packages.
Firstly, you'll need to enable CSRF protection, which the Go standard library has good support for as of Go 1.25; e.g.
csrf := http.NewCrossOriginProtection()
_ = csrf.AddTrustedOrigin("https://appleid.apple.com")
// ...
server := &http.Server{
Addr: address,
Handler: csrf.Handler(router),
}For getting users logged in via their oauth provider, you'll need to have handler(s) that go through the oauth handshake.
The cattlecloud.net/go/webtools module is opensource under the BSD-3-Clause license.