Go

Authenticate requests and manage Passage users with Go.

To use the Passage Go SDK, you'll need your Passage App ID. You can create a new Passage App in the console.

To use Passage in your Go application, run

go get github.com/passageidentity/passage-go

at the command line.

Authenticating a Request

Passage makes it easy to associate an HTTP request with an authenticated user. The following code can be used to validate that a request was made by an authenticated user.

import (
	"net/http"

	"github.com/passageidentity/passage-go"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {

	// Authenticate this request using the Passage SDK:
	psg, _ := passage.New("<PASSAGE_APP_ID>", nil)
	_, err := psg.AuthenticateRequest(r)
	if err != nil {
		// 🚨 Authentication failed!
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	// ✅ Authentication successful. Proceed...

}

By default, Passage looks for the user JWT from a cookie that is set by the Passage Element ( psg_auth_token ). If your application uses Authorization headers instead, you can pass the following option to the Passage Go SDK.

psg = Passage.new(PASSAGE_APP_ID,  &passage.Config{
    APIKey: PASSAGE_API_KEY,
    HeaderAuth: true,
})

Authorizing a User

It is important to remember that psg.AuthenticateRequest() validates that a request is properly authenticated and returns the authenticated user's Passage identifier, but an additional authorization check is typically required.

import (
	"net/http"

	"github.com/passageidentity/passage-go"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {

	// Authenticate this request using the Passage SDK:
	psg, _ := passage.New("<PASSAGE_APP_ID>", nil)
	passageID, err := psg.AuthenticateRequest(r)
	if err != nil {
		// 🚨 Authentication failed!
		w.WriteHeader(http.StatusUnauthorized)
		return
	}

	// ✋ Authentication successful, but let's check authorization:
	allowed := myAuthorizationCheck(passageID, "role.manager")
	if !allowed {
		// 🚨 Authorization failed!
		w.WriteHeader(http.StatusForbidden)
		return
	}
	
	// ✅ Authentication & authorization successful. Proceed...

}

App Information

The Passage SDK provides a way to retrieve information about an app.

import (
	"net/http"

	"github.com/passageidentity/passage-go"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {

  psg, _ := passage.New("<PASSAGE_APP_ID>", nil)
  
  passageAppInfo, err := psg.GetApp() 
  if err != nil {
    // 💀 Couldn't get the Passage App
    w.WriteHeader(http.StatusInternalServerError)
    return
  }
}

User Management

In addition to authenticating requests, the Passage SDK also provides a way to securely manage your users. These functions require authentication using a Passage API key. API keys can be managed in the Passage Console.

The functionality currently available on a user is:

  • Get a user's information (including any defined user metadata fields)

  • Activate or deactivate a user (a deactivated user will not be able to log in)

  • Update a user's information (email address or phone number)

  • Delete a user

  • Create a user

Passage API Keys are sensitive! You should store them securely along with your other application secrets.

import (
	"net/http"

	"github.com/passageidentity/passage-go"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {

  psg, _ := passage.New("<PASSAGE_APP_ID>", &passage.Config{
    APIKey: "<PASSAGE_API_KEY>",
  })
  passageUserID, err := psg.AuthenticateRequest(r)
  if err != nil {
    // Authentication failed!
    w.WriteHeader(http.StatusUnauthorized)
    return
  }
  
  // The passageUserID returned above can be used to get user information:
  passageUser, err := psg.GetUser(passageUserID) 
  if err != nil {
    // Couldn't get the Passage User
    w.WriteHeader(http.StatusInternalServerError)
    return
  }
  
  // The passageUser struct can now be inspected for detailed information
  // about the user. A full list of fields can be found here:
  //   https://pkg.go.dev/github.com/passageidentity/passage-go#User
  _ = passageUser

}

User Device Management

The functionality currently available is:

  • List all devices for a user

  • Revoke a particular device from a user

import (	
	"net/http"
	
	"github.com/passageidentity/passage-go"
)

func exampleHandler(w http.ResponseWriter, r *http.Request) {

  psg, _ := passage.New("<PASSAGE_APP_ID>", &passage.Config{
    APIKey: "<PASSAGE_API_KEY>",
  })

  // Get the Passage User ID from database
  
  // The passageUserID returned above can be used deactivate a user
  passageDevices, err := psg.ListUserDevices(passageUserID)
  if err != nil {
    // Couldn't list the user devices
    w.WriteHeader(http.StatusInternalServerError)
    return
  }

The Go SDK can be used to generate custom magic links for users, that can be embedded into any content medium. To learn more, see our full guide on Embedded Magic Links.

import (
    "github.com/passageidentity/passage-go"
    "fmt"
)

func main() {
    psg, err := passage.New(PASSAGE_APP_ID, &passage.Config{
        APIKey: PASSAGE_API_KEY,
    })
    
    createMagicLinkBody := passage.CreateMagicLinkBody{
        Email: "[email protected]",
        RedirectURL: "/custom-path/1234",
    }
    
    magicLink, err := psg.CreateMagicLink(createMagicLinkBody)
    // use magicLink.URL
    fmt.Println(magicLink.URL) 
}

Go Reference

For complete documentation on passage-go functions and types, check out the Go docs here.

Last updated