---
title: "Add JWT Authentication to Your Meteor API"
description: "Secure your Meteor API using JWT authentication with JWKS."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/javascript/meteor/jwt-backend"
framework: "Meteor"
language: "JavaScript"
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your Meteor API

Secure your Meteor API using JWT authentication with JWKS.

## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your Meteor backend can verify — no long-lived API keys touch your origin.

## Meteor Backend Code

```javascript
import { Meteor } from "meteor/meteor";
import { WebApp } from "meteor/webapp";
import jwt from "jsonwebtoken";
import jwksClient from "jwks-rsa";

// Constants
const ISSUER = "https://my-api-a32f34.zuplo.api/__zuplo/issuer";

// Create a JWKS client to fetch public keys
const client = jwksClient({
  jwksUri: `${ISSUER}/.well-known/jwks.json`,
  cache: true,
  cacheMaxAge: 600000, // 10 minutes
});

// Function to get the signing key
function getKey(header, callback) {
  client.getSigningKey(header.kid, (err, key) => {
    if (err) {
      return callback(err);
    }
    const signingKey = key.getPublicKey();
    callback(null, signingKey);
  });
}

// Middleware to validate JWT
function validateJwt(req, res, next) {
  const token = req.headers.authorization?.replace("Bearer ", "");

  if (!token) {
    res.writeHead(401);
    res.end(JSON.stringify({ error: "No token provided" }));
    return;
  }

  jwt.verify(
    token,
    getKey,
    {
      issuer: ISSUER,
      algorithms: ["RS256"],
    },
    (err, decoded) => {
      if (err) {
        res.writeHead(401);
        res.end(
          JSON.stringify({ error: "Invalid token", details: err.message }),
        );
        return;
      }
      req.user = decoded;
      next();
    },
  );
}

// Set up protected route
WebApp.connectHandlers.use("/protected", validateJwt, (req, res) => {
  res.writeHead(200);
  res.end(
    JSON.stringify({
      message: "Access granted",
      user: req.user,
    }),
  );
});

Meteor.startup(() => {
  // Meteor startup code
});
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
