Authenticating with local environment variables

When authenticating with an API using a SDK, its a common pattern for the value of an API_KEY or token to default to the value of an environment variable. This allows you to easily switch between different environments without changing the code.

In this example, we’ll show you how to use a SDK Hook enable your users to authenticate with your API using local environment variables. A SDK Hook is a function that will be executed by the SDK at a specific point in the request lifecycle. For this use case we’ll leverage a BeforeRequest hook.

Inside of our Speakeasy generated SDK hooks are written in the src/hooks/ directory. We’ll make a new hook called in a file called auth.ts.

src/hooks/auth.ts
import { BeforeRequestHook } from "./types";
export const injectAPIKey: BeforeRequestHook = {
beforeRequest: async (_, request) => {
const authz = request.headers.get("Authorization");
if (authz) {
return request;
}
let token = "";
if (typeof process !== "undefined") {
token = process.env["API_KEY"] ?? "";
}
if (!token) {
throw new Error("The API_KEY environment variable is missing or empty; either provide it");
}
request.headers.set("Authorization", `Bearer ${token}`);
return request;
},
};

This hook will check for the presence of an environment variable named API_KEY and if it exists, it will add it to the Authorization header of the request.

Finally to ensure the SDK uses this hook, we need to add it to make sure it is registered with the SDK. This is done in the src/hooks/registration.ts file.

src/hooks/registration.ts
import { injectAPIKey } from "./auth";
import { Hooks } from "./types";
/*
* This file is only ever generated once on the first generation and then is free to be modified.
* Any hooks you wish to add should be registered in the initHooks function. Feel free to define them
* in this file or in separate files in the hooks folder.
*/
export function initHooks(hooks: Hooks) {
// Add hooks by calling hooks.register{ClientInit/BeforeRequest/AfterSuccess/AfterError}Hook
// with an instance of a hook that implements that specific Hook interface
// Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance
hooks.registerBeforeRequestHook(injectAPIKey);
}

Finally make sure to update the usage snippet in your readme to reference the environment variable.