@stone-js/auth
v0.8.15
Published
Framework-agnostic, edge-native authentication for Stone.js. Stateless JWT/OAuth (access, id, refresh) built on jose — sign and verify tokens on Node, browser, Deno, Bun and the edge, with remote JWKS and scopes.
Maintainers
Readme
Stone.js · Auth
Framework-agnostic, edge-native authentication for Stone.js. Stateless JWT/OAuth (access, id, refresh) built on jose — sign and verify tokens on Node, browser, Deno, Bun and the edge, with remote JWKS and scopes.
Part of Stone.js, the reference implementation of the Continuum Architecture: write your domain once, and the context (runtime, protocol, caller) applies to it at run time.
Install
npm i @stone-js/authEnabling it
Like every Stone.js module, it is enabled in one of two ways, and configured afterwards under
stone.auth. It registers the authentication provider and the kernel middleware that verifies every request.
import { Auth } from '@stone-js/auth'
import { StoneApp } from '@stone-js/core'
@Auth({ secret: getString('JWT_SECRET'), issuer: 'https://issuer.example', audience: 'my-api' })
@StoneApp({ name: 'my-app' })
export class Application {}import { defineStoneApp } from '@stone-js/core'
import { authBlueprint } from '@stone-js/auth'
export const Application = defineStoneApp({ name: 'my-app' }, [authBlueprint])Configure it from a @Configuration class or defineConfig:
export const AppConfig = defineConfig((blueprint) => blueprint.set('stone.auth', { /* ... */ }))Usage
import { requireAuth, requireScopes } from '@stone-js/auth'
import { EventHandler, Get, Post } from '@stone-js/router'
@EventHandler('/tasks')
export class TaskController {
@Get('/', { middleware: [requireAuth()] }) // 401 when anonymous
list () { /* ... */ }
@Post('/', { middleware: [requireScopes('tasks:write')] }) // 403 without the scope
create (event) { /* ... */ }
}
// Enabled with @Auth() (or authBlueprint) on the application; the signing strategy is
// configured from a @Configuration: blueprint.set('stone.auth.secret', getString('JWT_SECRET'))Mapping the token to your own user
The verified claims describe the token, not your application's principal. resolveUser turns one
into the other, and it may be asynchronous: resolving a principal usually hits a store, and
that first lookup is often where the account gets provisioned.
blueprint.set('stone.auth.resolveUser', async (claims) => {
return await users.findOrCreateBySubject(claims.sub)
})The resolved value is what event.getUser() returns for the rest of the request. A synchronous
resolver works exactly the same way; omit the option entirely and the raw claims are used.
Documentation
Full documentation: stonejs.dev/docs/extensions/auth.
License
MIT © Evens Pierre ("Mr. Stone") and the Stone.js contributors.
