Appearance
Verifying the user's access token
Once you've obtained the user's access token from a request, you should verify the token against Privy's verification key for your app to confirm that the token was issued by Privy and the user referenced by the DID in the token is truly authenticated.
The access token is a standard ES256 JWT and the verification key is a standard Ed25519 public key. You can verify the access token against the public key using the @privy-io/server-auth
library or using a third-party library for managing tokens.
Using @privy-io/server-auth
Pass the user's access token as a string
to the PrivyClient
's verifyAuthToken
method:
tsx
// `privy` refers to an instance of the `PrivyClient`
try {
const verifiedClaims = await privy.verifyAuthToken(authToken);
} catch (error) {
console.log(`Token verification failed with error ${error}.`);
}
If the token is valid, verifyAuthToken
will return an AuthTokenClaims
object with additional information about the request, with the fields below:
Parameter | Type | Description |
---|---|---|
appId | string | Your Privy app ID. |
userId | string | The authenticated user's Privy DID. Use this to identify the requesting user. |
issuer | string | This will always be 'privy.io' . |
issuedAt | string | Timestamp for when the access token was signed by Privy. |
expiration | string | Timestamp for when the access token will expire. |
sessionId | string | Unique identifier for the user's session. |
If the token is invalid, verifyAuthToken
will throw an error and you should not consider the requesting user authorized. This generally occurs if the token has expired or is invalid (e.g. corresponds to a different app ID).
TIP
The Privy Client's verifyAuthToken
method will make a request to Privy's API to fetch the verification key for your app. You can avoid this API request by copying your verification key from the Settings page of the Dashboard and passing it as a second parameter to verifyAuthToken
:
ts
const verifiedClaims = await privy.verifyAuthToken(
authToken,
'paste-your-verification-key-from-the-dashboard',
);
Using a third-party library
See instructions below verifying access tokens using third-party libraries from various languages.
JavaScript/TypeScript
Two common libraries for verifying tokens in JavaScript/TypeScript are jose
and jsonwebtoken
.
To start, install jose
:
sh
npm i jose
Then, load your Privy public key using jose.importSPKI
:
tsx
const verificationKey = await jose.importSPKI('insert-your-privy-verification-key', 'ES256');
Lastly, using jose.jwtVerify
, verify that the JWT is valid and was issued by Privy!
tsx
const accessToken = 'insert-the-users-access-token';
try {
const payload = await jose.jwtVerify(accessToken, verificationKey, {
issuer: 'privy.io',
audience: 'insert-your-privy-app-id',
});
console.log(payload);
} catch (error) {
console.error(error);
}
If the JWT is valid, you can extract the JWT's claims from the payload
. For example, you can use payload.sub
to get the user's Privy DID.
If the JWT is invalid, this method will throw an error.
Go
For Go, the golang-jwt
library is a popular choice for token verification. To start, install the library:
sh
go get -u github.com/golang-jwt/jwt/v5
Next, load your Privy verification key and app ID as strings:
go
verificationKey := "insert-your-privy-verification-key"
appId := "insert-your-privy-app-id"
Then, parse the claims from the JWT and verify that they are valid:
go
accessToken := "insert-the-users-access-token"
// Defining a Go type for Privy JWTs
type PrivyClaims struct {
AppId string `json:"aud,omitempty"`
Expiration uint64 `json:"exp,omitempty"`
Issuer string `json:"iss,omitempty"`
UserId string `json:"sub,omitempty"`
}
// This method will be used to check the token's claims later
func (c *PrivyClaims) Valid() error {
if c.AppId != appId {
return errors.New("aud claim must be your Privy App ID.")
}
if c.Issuer != "privy.io" {
return errors.New("iss claim must be 'privy.io'")
}
if c.Expiration < uint64(time.Now().Unix()) {
return errors.New("Token is expired.");
}
return nil
}
// This method will be used to load the verification key in the required format later
func keyFunc(token *jwt.Token) (interface{}, error) {
if token.Method.Alg() != "ES256" {
return nil, fmt.Errorf("Unexpected JWT signing method=%v", token.Header["alg"])
}
// https://pkg.go.dev/github.com/dgrijalva/jwt-go#ParseECPublicKeyFromPEM
return jwt.ParseECPublicKeyFromPEM([]byte(verificationKey)), nil
}
// Check the JWT signature and decode claims
// https://pkg.go.dev/github.com/dgrijalva/jwt-go#ParseWithClaims
token, err := jwt.ParseWithClaims(accessToken, &PrivyClaims{}, keyFunc)
if err != nil {
fmt.Println("JWT signature is invalid.")
}
// Parse the JWT claims into your custom struct
privyClaim, ok := token.Claims.(*PrivyClaims)
if !ok {
fmt.Println("JWT does not have all the necessary claims.")
}
// Check the JWT claims
err = Valid(privyClaim);
if err {
fmt.Printf("JWT claims are invalid, with error=%v.", err);
fmt.Println();
} else {
fmt.Println("JWT is valid.")
fmt.Printf("%v", privyClaim)
}
If the JWT is valid, you can access its claims, including the user's DID, from the privyClaim
struct above.
If the JWT is invalid, an error will be thrown.
Python
For Python, the pyjwt
library is a popular choice for token verification.
To start, install the library:
sh
pip install PyJWT
Next, load your Privy public key and app ID as variables:
python
verificationKey = 'insert-your-privy-verification-key'
appId = 'insert-your-privy-app-id'
Lastly, verify that your JWT is valid using the library's decode
method:
python
accessToken = 'insert-the-users-access-token'
try:
decoded = jwt.decode(authToken, verificationKey, issuer='privy.io', audience=appId, algorithms=['ES256'])
print(decoded)
except:
print("Token verification failed")
If the JWT is valid, you can extract the JWT's claims from the decoded
object. For example, you can use decoded['sub']
to get the user's Privy DID.
If the JWT is invalid, decode
will throw an error.