샘플
hono 4.13.1: bearer-auth
검증된 샘플 — npm hono 4.13.1: bearer-auth. node 22 · linux debian/x64 · docker에서 contract를 실행해 통과했습니다: assert bearerAuth is exported as a function from…
sha256:2d4eefa45fd8c7c70c76c1dae4176e893170476d2c405b78836d5be4c9f78a34
이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다.
통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다.
MIT-0
실행 증거
선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.
- 증거 기준
- 서명된 컨트랙트 통과
- 검증 영수증
- 1
- 빌드한 서명 키
- 1
선언된 환경
node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10
검증 실행 환경
| 환경 | 컨트랙트 | 단계 | 실행일 |
|---|---|---|---|
| node 22 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2… |
2026-09-01 |
케이스
HOW- 목표
- verify hono/bearer-auth in pkg:npm/hono@4.13.1
- 패키지
- 심벌
-
- hono/bearer-auth
- 환경
- node 22.23.2
- 생성일
- 2026-09-01T19:51:44Z
컨트랙트
- assert bearerAuth is exported as a function from hono/bearer-auth
- assert bearerAuth grants access with 200 OK when valid static bearer token is provided
- assert bearerAuth returns 401 Unauthorized with WWW-Authenticate header when authorization header is missing
- assert bearerAuth returns 400 Bad Request when authorization header prefix is malformed
- assert bearerAuth returns 401 Unauthorized with invalid_token error when token does not match
- assert bearerAuth supports multiple valid tokens configured as an array
- assert bearerAuth supports custom verifyToken predicate function
- assert bearerAuth supports custom headerName and custom prefix
- assert bearerAuth supports custom realm and custom error messages
파일
- PROMPT.md
- csx.json
- index.mjs
- package-lock.json
- package.json
- spec.json
- test/contract.mjs
소스
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify hono/bearer-auth in pkg:npm/hono@4.13.1
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/hono@4.13.1
Demonstrate these symbols/APIs:
- hono/bearer-auth
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:5b137ee068f37e934a117a992930bf88f774c27c0c856a7ad4384b4be7f540db","contract":["assert bearerAuth is exported as a function from hono/bearer-auth","assert bearerAuth grants access with 200 OK when valid static bearer token is provided","assert bearerAuth returns 401 Unauthorized with WWW-Authenticate header when authorization header is missing","assert bearerAuth returns 400 Bad Request when authorization header prefix is malformed","assert bearerAuth returns 401 Unauthorized with invalid_token error when token does not match","assert bearerAuth supports multiple valid tokens configured as an array","assert bearerAuth supports custom verifyToken predicate function","assert bearerAuth supports custom headerName and custom prefix","assert bearerAuth supports custom realm and custom error messages"],"goal":"verify hono/bearer-auth in pkg:npm/hono@4.13.1","kind":"HOW","packages":["pkg:npm/hono@4.13.1"],"schemaVersion":1,"symbols":["hono/bearer-auth"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"esm","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/hono@4.13.1"],"schemaVersion":1,"subject":"pkg:npm/hono@4.13.1","symbols":["hono/bearer-auth"],"verifierAdapter":"node-typescript@1"}
import { Hono } from 'hono';
import { bearerAuth } from 'hono/bearer-auth';
export { bearerAuth };
/**
* Creates a Hono application protected by bearerAuth middleware.
* @param {import('hono/bearer-auth').BearerAuthOptions} options
* @returns {Hono}
*/
export function createProtectedApp(options) {
const app = new Hono();
app.use('/api/*', bearerAuth(options));
app.get('/api/resource', (c) => c.json({ status: 'ok', message: 'access granted' }));
return app;
}
{
"name": "sample-hono-bearer-auth",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-hono-bearer-auth",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"hono": "4.13.1"
}
},
"node_modules/hono": {
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.1.tgz",
"integrity": "sha512-kdJoFVv2xmayw6cY09H7AbMJMt8Jn5jdlEdXsP7AGBdF2DIptVlKlOLKXP41yPip4/a3yQPv9gVcJYI8YY04dw==",
"license": "MIT",
"engines": {
"node": ">=16.9.0"
}
}
}
}
{
"name": "sample-hono-bearer-auth",
"version": "1.0.0",
"description": "Clean-room sample verifying hono/bearer-auth in hono",
"type": "module",
"main": "index.mjs",
"license": "MIT-0",
"dependencies": {
"hono": "4.13.1"
}
}
{
"schemaVersion": 1,
"goal": "verify hono/bearer-auth in pkg:npm/hono@4.13.1",
"kind": "HOW",
"packages": [
"pkg:npm/hono@4.13.1"
],
"symbols": [
"hono/bearer-auth"
]
}
import assert from 'node:assert';
import { bearerAuth } from 'hono/bearer-auth';
import { createProtectedApp } from '../index.mjs';
// 1. assert bearerAuth is exported as a function from hono/bearer-auth
assert.strictEqual(typeof bearerAuth, 'function', 'bearerAuth must be a function');
// 2. assert bearerAuth grants access with 200 OK when valid static bearer token is provided
const singleTokenApp = createProtectedApp({ token: 'secret-token-123' });
const resValid = await singleTokenApp.request('/api/resource', {
headers: { Authorization: 'Bearer secret-token-123' },
});
assert.strictEqual(resValid.status, 200, 'Valid bearer token must return 200 OK');
const validData = await resValid.json();
assert.deepStrictEqual(validData, { status: 'ok', message: 'access granted' }, 'Response body must match protected handler output');
// 3. assert bearerAuth returns 401 Unauthorized with WWW-Authenticate header when authorization header is missing
const resNoHeader = await singleTokenApp.request('/api/resource');
assert.strictEqual(resNoHeader.status, 401, 'Missing authorization header must return 401 Unauthorized');
assert.strictEqual(resNoHeader.headers.get('www-authenticate'), 'Bearer realm=""', 'Must set WWW-Authenticate realm header on missing auth');
// 4. assert bearerAuth returns 400 Bad Request when authorization header prefix is malformed
const resBadFormat = await singleTokenApp.request('/api/resource', {
headers: { Authorization: 'Basic secret-token-123' },
});
assert.strictEqual(resBadFormat.status, 400, 'Invalid auth header prefix format must return 400 Bad Request');
// 5. assert bearerAuth returns 401 Unauthorized with invalid_token error when token does not match
const resWrongToken = await singleTokenApp.request('/api/resource', {
headers: { Authorization: 'Bearer incorrect-token' },
});
assert.strictEqual(resWrongToken.status, 401, 'Incorrect bearer token must return 401 Unauthorized');
assert.strictEqual(resWrongToken.headers.get('www-authenticate'), 'Bearer error="invalid_token"', 'Must set WWW-Authenticate error on invalid token');
// 6. assert bearerAuth supports multiple valid tokens configured as an array
const multiTokenApp = createProtectedApp({ token: ['token-alpha', 'token-beta'] });
const resAlpha = await multiTokenApp.request('/api/resource', {
headers: { Authorization: 'Bearer token-alpha' },
});
assert.strictEqual(resAlpha.status, 200, 'First token in multi-token array must return 200 OK');
const resBeta = await multiTokenApp.request('/api/resource', {
headers: { Authorization: 'Bearer token-beta' },
});
assert.strictEqual(resBeta.status, 200, 'Second token in multi-token array must return 200 OK');
const resGamma = await multiTokenApp.request('/api/resource', {
headers: { Authorization: 'Bearer token-gamma' },
});
assert.strictEqual(resGamma.status, 401, 'Unlisted token in multi-token array must return 401 Unauthorized');
// 7. assert bearerAuth supports custom verifyToken predicate function
const customVerifyApp = createProtectedApp({
verifyToken: async (token, c) => {
return token === 'dynamic-valid' && c.req.path === '/api/resource';
},
});
const resDynamicValid = await customVerifyApp.request('/api/resource', {
headers: { Authorization: 'Bearer dynamic-valid' },
});
assert.strictEqual(resDynamicValid.status, 200, 'verifyToken returning true must grant access');
const resDynamicInvalid = await customVerifyApp.request('/api/resource', {
headers: { Authorization: 'Bearer dynamic-invalid' },
});
assert.strictEqual(resDynamicInvalid.status, 401, 'verifyToken returning false must return 401 Unauthorized');
// 8. assert bearerAuth supports custom headerName and custom prefix
const customHeaderApp = createProtectedApp({
headerName: 'x-api-key',
prefix: 'Token',
token: 'custom-header-secret',
});
const resCustomHeaderValid = await customHeaderApp.request('/api/resource', {
headers: { 'x-api-key': 'Token custom-header-secret' },
});
assert.strictEqual(resCustomHeaderValid.status, 200, 'Custom header and prefix must grant access');
const resCustomHeaderWrongPrefix = await customHeaderApp.request('/api/resource', {
headers: { 'x-api-key': 'Bearer custom-header-secret' },
});
assert.strictEqual(resCustomHeaderWrongPrefix.status, 400, 'Mismatched prefix on custom header must return 400 Bad Request');
// 9. assert bearerAuth supports custom realm and custom error messages
const customMessagesApp = createProtectedApp({
token: 'msg-token',
realm: 'secure-api',
noAuthenticationHeaderMessage: 'No token header',
invalidAuthenticationHeaderMessage: 'Invalid prefix scheme',
invalidTokenMessage: 'Token verification failed',
});
const resCustomNoHeader = await customMessagesApp.request('/api/resource');
assert.strictEqual(resCustomNoHeader.status, 401, 'Custom message app missing header must return 401');
assert.strictEqual(await resCustomNoHeader.text(), 'No token header', 'Custom noAuthenticationHeaderMessage must be returned');
assert.strictEqual(resCustomNoHeader.headers.get('www-authenticate'), 'Bearer realm="secure-api"', 'Custom realm must be reflected in header');
const resCustomBadPrefix = await customMessagesApp.request('/api/resource', {
headers: { Authorization: 'Digest 12345' },
});
assert.strictEqual(resCustomBadPrefix.status, 400, 'Custom message app bad prefix must return 400');
assert.strictEqual(await resCustomBadPrefix.text(), 'Invalid prefix scheme', 'Custom invalidAuthenticationHeaderMessage must be returned');
const resCustomWrongToken = await customMessagesApp.request('/api/resource', {
headers: { Authorization: 'Bearer wrong-msg-token' },
});
assert.strictEqual(resCustomWrongToken.status, 401, 'Custom message app wrong token must return 401');
assert.strictEqual(await resCustomWrongToken.text(), 'Token verification failed', 'Custom invalidTokenMessage must be returned');
console.log('All hono/bearer-auth contract assertions passed.');
오리진 시더
익명