Skip to content

Guards

You can protect your routes with guards.

A guard allows you to execute logic before a certain request reaches a designated route handler.

Start by adding a guard to the server

package main
import (
"github.com/razshare/frizzante/connections"
"github.com/razshare/frizzante/guards"
"github.com/razshare/frizzante/routes"
"github.com/razshare/frizzante/servers"
)
var server = servers.New() // Creates a server.
func main() {
server.Guards = append(server.Guards, { // Adds a guard.
Name: "No Json Allowed", // Sets the guard's name. It's useful for logs.
Handler: func(connection *connections.Connection, allow func()) { // Sets the guard's handler.
if connection.VerifyContentType("application/json") { // If requests uses "application/json" content...
return // ..returns. This will actually terminate the connection.
}
allow() // Allows the request through.
},
Tags: []string{"nojson", "jsonless"}, // Sets the guard's tags.
})
server.AddRoute(routes.Route{ // Adds a route.
Pattern: "GET /", // Sets the route's pattern.
Handler: func(connection *connections.Connection) {
connection.SendMessage("Hello.") // Sends text.
},
Tags: []string{"nojson"}, // Sets the route's tags. Any guard that intersects
// with these tags will execute before any
// request reaches the route's handler.
})
server.Start() // Starts the server.
}

A guard protects every route whose tags intersect with at least one of its own tags.

In this case, the GET / route intersects with the No Json Allowed guard in nojson, which means GET / is protected by No Json Allowed.

Multiple guards can intersect in order to compose more advanced restrictions.

server.Guards = append(server.Guards, { // Adds a guard.
Name: "Authorization", // Sets the guard's name. It's useful for logs.
Handler: func(connection *connections.Connection, allow func()) { // Sets the guard's handler. If allow() is never invoked,
// the guard will reject the request.
auth := connection.ReceiveHeader("Authorization") // Gets the "Authorization" header from the request.
if !SuperAdvancedAuthorizationCheckTM(auth) { // If user is not authorized...
connection.SendStatus(403) // ...sends status 403...
connection.SendMessage("Not authorized.") // ...and a short message with an explanation.
return // Returns. This will actually terminate the connection.
}
allow() // Allows the request through.
},
Tags: []string{"authorization", "auth"}, // Sets the guard's tags.
})
server.Guards = append(server.Guards, { // Adds a guard.
Name: "Authentication", // Sets the guard's name. It's useful for logs.
Handler: func(connection *connections.Connection, allow func()) { // Sets the guard's handler. If allow() is never invoked,
// the guard will reject the request.
session := sessions.New(connection, State{}).Start() // Starts the session.
if !session.State.SignedIn { // If the use is not signed in...
connection.SendStatus(403) // ...sends status 403...
connection.SendMessage("Not authenticated.") // ...and a short message with an explanation.
return // Returns. This will actually terminate the connection.
}
allow() // Allows the request through.
},
Tags: []string{"authentication", "auth"}, // Sets the guard's tags.
})
server.Guards = append(server.Guards, { // Adds a route.
Pattern: "GET /", // Sets the route's pattern.
Handler: func(connection *connections.Connection) { // Sets the route's handler.
connection.SendMessage("Hello.") // Sends text.
},
Tags: []string{"auth"}, // Sets the route's tags. Any guard that intersects
// with these tags will execute before any
// request reaches the route's handler.
})

In this case, GET / is protected by both Authentication and Authorization guards because they all intersect int auth.