CORS & Auth Basics AI-generated

CORS

CORS is on by default for every mock service (turn it off via Generate CORS Headers: Disabled under a Service's Fine-Tuning section, see Services - useful if you want to author the headers yourself, or deliberately test a client against a CORS-non-compliant backend). Response headers are only ever generated when the request itself carries an Origin header - non-browser calls (plain SOAP, server-to-server) are unaffected either way. Exact behavior depends on the request shape:

  • Every request with an Origin gets Access-Control-Allow-Origin set to that exact origin (never *), Access-Control-Allow-Credentials: true (so that fetch() with credentials: "include" works; no credentials are ever sent back), and Access-Control-Allow-Methods with the method of the request. An OPTIONS that does not say which method it asks about gets all the methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS.
  • Preflight requests - a browser's OPTIONS probe ahead of a non-simple method/header - get Access-Control-Allow-Methods and Access-Control-Allow-Headers echoing back exactly what the browser asked for, plus Access-Control-Max-Age: 7200 so that the browser remembers the answer for two hours (the longest time every browser honours) instead of asking before each call. A preflight for a private network (Access-Control-Request-Private-Network) is answered with Access-Control-Allow-Private-Network: true. A request that carries Authorization also gets Authorization in Access-Control-Allow-Headers, which the * wildcard would not cover.
  • Other requests get Access-Control-Expose-Headers listing the headers of the response that the page script could not read otherwise: every one except the always readable ones (Cache-Control, Content-Language, Content-Length, Content-Type, Expires, Last-Modified, Pragma), Set-Cookie and the connection-level ones. Your own custom headers and the generated ETag are in the list.
  • Vary is * unless the reaction sets its own, which means that nothing is cached (the generated ETag is random). If the reaction sets its own Vary without Origin, Origin is added to it, since the answer depends on the origin.
  • Forwarded responses - a reaction that forwards to another server - have the upstream Access-Control-Allow-Origin replaced by the origin of the caller. What the upstream server allows is of no use to this caller; everything else the upstream says stays.
  • Errors - a script error or any other HTTP 500 raised by MockMotor - carry the same headers as the successful answers of a service with CORS enabled, so that the page can read the error. A service with Generate CORS Headers: Disabled gets none, errors included.

To override the automatically-generated headers for a specific reaction, set them explicitly in that reaction's Custom Headers section (see Reactions) - an explicit header there wins over the automatic one, except in a forwarded response, whose Access-Control-Allow-Origin is always the caller's. If the reaction sets Access-Control-Allow-Origin: *, Access-Control-Allow-Credentials is not added: browsers reject that combination.

Basic HTTP Authentication

To mock an endpoint that requires HTTP Basic Auth, match on the presence/value of the Authorization header in a reaction's Match Options script (e.g. http.headers['Authorization']==null for the "missing credentials" case), and set that reaction's status to 401 with a WWW-Authenticate response header - ordinary reaction authoring, no special Basic Auth feature needed.

JWT-secured mocks

MockMotor has a native JWT object available to JavaScript reactions (not XQuery ones) for signing, decoding and verifying tokens, using the HS256, HS384 or HS512 algorithms - enough to build a small, fully self-contained mock login+authenticated-endpoint flow without any external auth service.

FunctionDoes
JWT.encode(header, payload, secret)Signs a new token. var token = JWT.encode(header, payload, "password123");
JWT.decode(token, secret)Parses a token to JSON without verifying it - adds an error field if it's malformed.
JWT.verify(token, secret)Decodes and validates - a bad signature or unsupported algorithm is a hard error (HTTP 500), not a soft failure.

Three fields are auto-populated from an incoming Authorization: Bearer <token> header, so you rarely need to parse it yourself: JWT.token (the raw token string, or null), JWT.header and JWT.payload (parsed objects, or {} if there's no token). Common uses: generate a token as part of a mocked login response; read JWT.payload fields to drive account selection/routing on a subsequent "authenticated" request; check standard claims like exp (expiration) or nbf (not-before) to simulate an expired- or not-yet-valid-token error.