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")funcexampleHandler(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.
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.
The Passage SDK provides a way to retrieve information about an app.
import ("net/http""github.com/passageidentity/passage-go")funcexampleHandler(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")funcexampleHandler(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")funcexampleHandler(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")funcexampleHandler(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{ Email: "[email protected]", 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")funcexampleHandler(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")funcexampleHandler(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 usertypeCreateUserBodystruct { Email string`json:"email,omitempty"` Phone string`json:"phone,omitempty"` } passageUser, err := psg.CreateUser(CreateUserBody{ Email: "[email protected]" })if err !=nil {// Couldn't create the user w.WriteHeader(http.StatusInternalServerError)return }
import ("net/http""github.com/passageidentity/passage-go")funcexampleHandler(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 passage user email can be used to get user information: passageUser, err := psg.GetByIdentifier("<PASSAGE_USER_EMAIL>") 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")funcexampleHandler(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")funcexampleHandler(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 }
Creating Magic Links
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.