Skip to content

Authentication

@t-req/core supports various authentication patterns through variables, resolvers, and cookies.

The most common pattern—extract a token from login and use it for subsequent requests:

auth/login.http
POST https://api.example.com/auth/login
Content-Type: application/json
{"email": "{{email}}", "password": "{{password}}"}
import { createClient } from '@t-req/core';
import { createNodeIO } from '@t-req/core/runtime';
const client = createClient({
io: createNodeIO(),
variables: {
email: 'user@example.com',
password: 'secret',
},
});
// Login and extract token
const loginResponse = await client.run('./auth/login.http');
const { token } = await loginResponse.json();
// Store token for subsequent requests
client.setVariable('token', token);
// Use in authenticated requests
const profile = await client.run('./users/profile.http');
users/profile.http
GET https://api.example.com/users/me
Authorization: Bearer {{token}}

Use a resolver to encode credentials:

const client = createClient({
io: createNodeIO(),
resolvers: {
$basicAuth: (username, password) => {
const credentials = `${username}:${password}`;
return Buffer.from(credentials).toString('base64');
},
},
variables: {
username: 'admin',
password: 'secret',
},
});
GET https://api.example.com/admin
Authorization: Basic {{$basicAuth({{username}}, {{password}})}}

Note: Variables inside resolver calls are interpolated first. The expression {{$basicAuth({{username}}, {{password}})}} first becomes {{$basicAuth(admin, secret)}}, then the resolver is called with literal strings "admin" and "secret".

Or pre-encode in the variable:

const client = createClient({
variables: {
basicAuth: Buffer.from('admin:secret').toString('base64'),
},
});
GET https://api.example.com/admin
Authorization: Basic {{basicAuth}}
GET https://api.example.com/data
X-API-Key: {{apiKey}}
GET https://api.example.com/data?api_key={{apiKey}}
const client = createClient({
io: createNodeIO(),
resolvers: {
$env: (key) => process.env[key] || '',
},
});
GET https://api.example.com/data
X-API-Key: {{$env(API_KEY)}}
auth/oauth-token.http
POST https://auth.example.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id={{clientId}}&client_secret={{clientSecret}}
const client = createClient({
io: createNodeIO(),
variables: {
clientId: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
},
});
const tokenResponse = await client.run('./auth/oauth-token.http');
const { access_token, expires_in } = await tokenResponse.json();
client.setVariable('accessToken', access_token);
// Use the token
const data = await client.run('./api/data.http');

Implement automatic token refresh:

async function withAuth<T>(
fn: () => Promise<Response>
): Promise<Response> {
const response = await fn();
if (response.status === 401) {
// Token expired, refresh it
const refreshResponse = await client.run('./auth/refresh.http');
const { token } = await refreshResponse.json();
client.setVariable('token', token);
// Retry the original request
return await fn();
}
return response;
}
const profile = await withAuth(() => client.run('./users/profile.http'));

Use the cookie jar for session-based authentication:

import { createClient } from '@t-req/core';
import { createNodeIO } from '@t-req/core/runtime';
import { createCookieJar } from '@t-req/core/cookies';
const client = createClient({
io: createNodeIO(),
cookieJar: createCookieJar(),
});
// Login sets session cookie automatically
await client.run('./auth/login.http');
// Subsequent requests include the session cookie
const profile = await client.run('./users/profile.http');

See Cookies for more details on cookie management.

For APIs requiring different auth for different endpoints:

// Admin client
const adminClient = createClient({
io: createNodeIO(),
variables: { token: adminToken },
});
// User client
const userClient = createClient({
io: createNodeIO(),
variables: { token: userToken },
});
// Or switch contexts dynamically
client.setVariable('token', isAdmin ? adminToken : userToken);