Search
⌃K
Links

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.
Get
Activate / Deactivate
Update
Delete
Create
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
}
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
deactivatedUser, err := psg.DeactivateUser(passageUserID)
if err != nil {
// 💀 Couldn't deactivate the user
w.WriteHeader(http.StatusInternalServerError)
return
}
// The passageUserID returned above can be used activate a user
activatedUser, err := psg.ActivateUser(passageUserID)
if err != nil {
// 💀 Couldn't activate the user
w.WriteHeader(http.StatusInternalServerError)
return
}
}
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
userUpdateAttributes := UpdateBody{
Phone: "+15005550006"
}
passageUser, err := psg.updateUser(passageUserID, userUpdateAttributes)
if err != nil {
// 😔 failed to update the user
w.WriteHeader(http.StatusInternalServerError)
return
}
}
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
passageUser, err := psg.DeleteUser(passageUserID)
if err != nil {
// 💀 Couldn't delete the user
w.WriteHeader(http.StatusInternalServerError)
return
}
}
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
type CreateUserBody struct {
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
}
passageUser, err := psg.CreateUser(CreateUserBody{
})
if err != nil {
// 💀 Couldn't create the user
w.WriteHeader(http.StatusInternalServerError)
return
}
}

User Device Management

The functionality currently available is:
  • List all devices for a user
  • Revoke a particular device from a user
List Devices
Revoke Device
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
}
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
success, err := psg.RevokeUserDevice(passageUserID, passageDeviceID)
if err != nil {
// 💀 Couldn't delete the device
w.WriteHeader(http.StatusInternalServerError)
return
}
The Go SDK can be used to generate custom magic links (called "smart links") for users, that can be embedded into any content medium. To learn more, see our full guide on Smart 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{
RedirectURL: "/custom-path/1234",
}
magicLink, err := psg.CreateMagicLink(createMagicLinkBody)
// use magicLink.URL
fmt.Println(magicLink.URL)
}

Go Reference

Go Reference
For complete documentation on passage-go functions and types, check out the Go docs here.
Last modified 5mo ago