HTTP request verification
At their most basic, apps are web pages embedded in an iframe. As a result, they have access to many standard web APIs, including the Fetch API(opens in a new tab or window).
Using the Fetch API in an app is the same as using it anywhere else, but before you can release your app publicly, we require that your app's backend verifies the authenticity of incoming requests. This ensures that requests are arriving from the app and not from some other, potentially malicious source.
For Node.js backends, the @canva/app-middleware(opens in a new tab or window) package simplifies the verification process by automatically handling token extraction, JWKS fetching, and JWT validation.
Some standard web APIs aren't available. To learn more, see Content Security Policy.
Step 1: Get a JWT from Canva
Before an app sends an HTTP request to its backend, it must request a JSON Web Token (JWT) from Canva. The app's backend can use this JWT to verify that the request is legitimate.
To get a JWT:
-
Import the
authnamespace from the@canva/userpackage:import { auth } from "@canva/user";TS -
Call the
getCanvaUserTokenmethod:const token = await auth.getCanvaUserToken();TSThis method returns a JWT as a string.
Step 2: Send a request
-
Use the Fetch API, or a library such as axios(opens in a new tab or window), to send an HTTP request:
const response = await fetch("http://localhost:3001/my/api/endpoint");TS -
In the headers of the request, include an
Authorizationheader:const response = await fetch("http://localhost:3001/my/api/endpoint", {headers: {Authorization: `Bearer ${token}`,},});TSThe header should contain the word
Bearerand the JWT, separated by a space.
Step 3: Verify the request
To verify the request, you can either use the @canva/app-middleware package (recommended), or manually implement your own verification.
Recommended: Using @canva/app-middleware
For Node.js backends, use the @canva/app-middleware package to automatically verify requests:
Express.js middleware
import express from "express";import { user } from "@canva/app-middleware/express";const app = express();// Apply middleware to verify all requestsapp.use("/my/api", user.verifyToken({ appId: process.env.CANVA_APP_ID }));app.post("/my/api/endpoint", (req, res) => {// Access verified user informationconst { userId, brandId } = req.canva.user;// Your application logic hereres.sendStatus(200);});app.listen(process.env.PORT || 3000);
For more information, see user.verifyToken.
Framework-agnostic approach
For other Node.js environments:
import { initUserTokenVerifier } from "@canva/app-middleware";// Initialize once at app startupconst userTokenVerifier = initUserTokenVerifier({appId: process.env.CANVA_APP_ID,});// In your request handlerasync function handleRequest(request) {const authHeader = request.headers.authorization;const token = authHeader?.replace("Bearer ", "");if (!token) {return { status: 401, body: "Unauthorized" };}try {const { userId, brandId } = await userTokenVerifier.verify(token);// Your application logic herereturn { status: 200, body: "Success" };} catch (error) {return { status: 401, body: "Unauthorized" };}}
For more information, see initUserTokenVerifier.
Alternative: Manual verification
If you're using a non-Node.js backend, you can manually extract and verify JWTs. Here's an example using Python with Flask:
Step 3a: Extract the JWT
When the backend receives a request, extract the JWT from the Authorization header:
from flask import Flask, request, jsonifyfrom functools import wrapsapp = Flask(__name__)def extract_token(auth_header):"""Extract JWT from Authorization header"""if not auth_header:return Noneparts = auth_header.split()if len(parts) != 2 or parts[0].lower() != 'bearer':return Nonereturn parts[1]@app.route('/my/api/endpoint', methods=['POST'])def api_endpoint():auth_header = request.headers.get('Authorization')token = extract_token(auth_header)if not token:return jsonify({'error': 'Unauthorized'}), 401# Verify token (see next step)# ...return jsonify({'message': 'Success'}), 200
If the Authorization header doesn't contain a token, reject the request with a 401 status code.
Step 3b: Verify the JWT
By itself, the JWT is an indecipherable string. To get useful information out of the JWT, it needs to be decoded and verified. To learn how to do this, see JSON Web Tokens.
Step 3c: Reject invalid requests
The verified JWT is an object that should contain the following properties:
aud- The ID of the app.brandId- The ID of the user's team.userId- The ID of the user.
If any of these properties aren't available, reject the request with a 401 status code:
if not verified.aud or not verified.brandId or not verified.userId:return jsonify({'error': 'Unauthorized'}), 401