Skip to content

Auth Middleware API Reference

Complete API reference for authentication middleware functions.

requireAuth()

Requires authenticated user. Throws 401 if not authenticated.

Signature

typescript
function requireAuth(): MiddlewareHandler

Returns

MiddlewareHandler - Hono middleware function

Behavior

  1. Extracts session ID from request (header, cookie, or query)
  2. Validates session with Bridge Validator
  3. Sets user context in Hono context
  4. Throws HTTPException(401) if validation fails
  5. Continues to next middleware if successful

Context Variables Set

VariableTypeDescription
user_idstringUser ID
sessionSessionDataFull session data
is_guestbooleanAlways false

Example

typescript
import { Hono } from 'hono';
import { requireAuth } from './lib/auth/middleware';

const app = new Hono();

app.get('/api/profile', requireAuth(), async (c) => {
  const userId = c.get('user_id');
  const session = c.get('session');
  
  return c.json({
    userId,
    email: session.email,
    name: session.name
  });
});

Error Responses

typescript
// 401 - No session ID provided
{
  "error": "Session ID required"
}

// 401 - Invalid session
{
  "error": "Invalid session"
}

// 500 - Service unavailable
{
  "error": "Authentication service unavailable"
}

optionalAuth()

Optional authentication. Allows guest access.

Signature

typescript
function optionalAuth(): MiddlewareHandler

Returns

MiddlewareHandler - Hono middleware function

Behavior

  1. Extracts session ID from request (if present)
  2. Validates session if provided
  3. Sets user context if valid
  4. Sets guest context if no session or invalid
  5. Never throws errors - always continues

Context Variables Set

Authenticated User:

VariableTypeDescription
user_idstringUser ID
sessionSessionDataFull session data
is_guestbooleanfalse

Guest User:

VariableTypeDescription
user_idundefinedNot set
sessionundefinedNot set
is_guestbooleantrue

Example

typescript
import { Hono } from 'hono';
import { optionalAuth } from './lib/auth/middleware';

const app = new Hono();

app.get('/api/posts', optionalAuth(), async (c) => {
  const userId = c.get('user_id');
  const isGuest = c.get('is_guest');
  
  if (isGuest) {
    // Show public posts only
    return c.json({ posts: await getPublicPosts() });
  } else {
    // Show personalized posts
    return c.json({ posts: await getPersonalizedPosts(userId) });
  }
});

requireUserType()

Requires specific user type(s). Throws 403 if user type doesn't match.

Signature

typescript
function requireUserType(userTypes: string | string[]): MiddlewareHandler

Parameters

ParameterTypeRequiredDescription
userTypesstring | string[]✅ YesAllowed user type(s)

Returns

MiddlewareHandler - Hono middleware function

Behavior

  1. Requires authentication (calls requireAuth() internally)
  2. Checks if user's type matches allowed types
  3. Throws HTTPException(403) if type doesn't match
  4. Continues if type matches

Example

typescript
import { Hono } from 'hono';
import { requireUserType } from './lib/auth/middleware';

const app = new Hono();

// Single user type
app.get('/api/admin/users', requireUserType('admin'), async (c) => {
  const users = await db.selectFrom('users').selectAll().execute();
  return c.json({ users });
});

// Multiple user types
app.get('/api/staff/dashboard', 
  requireUserType(['admin', 'staff', 'support']), 
  async (c) => {
    return c.json({ dashboard: 'Staff Dashboard' });
  }
);

Error Responses

typescript
// 401 - Not authenticated
{
  "error": "Authentication required"
}

// 403 - Wrong user type
{
  "error": "Insufficient permissions. Required user types: admin"
}

requirePermission()

Requires specific permission. Throws 403 if permission not granted.

Signature

typescript
function requirePermission(permission: string): MiddlewareHandler

Parameters

ParameterTypeRequiredDescription
permissionstring✅ YesRequired permission

Returns

MiddlewareHandler - Hono middleware function

Behavior

  1. Requires authentication (calls requireAuth() internally)
  2. Checks if user has the required permission
  3. Admins bypass permission checks
  4. Throws HTTPException(403) if permission not granted
  5. Continues if permission granted

Example

typescript
import { Hono } from 'hono';
import { requirePermission } from './lib/auth/middleware';

const app = new Hono();

app.delete('/api/posts/:id', 
  requirePermission('posts.delete'), 
  async (c) => {
    const postId = c.req.param('id');
    await db.deleteFrom('posts').where('id', '=', postId).execute();
    return c.json({ success: true });
  }
);

app.post('/api/users', 
  requirePermission('users.create'), 
  async (c) => {
    const data = await c.req.json();
    const user = await createUser(data);
    return c.json({ user });
  }
);

Error Responses

typescript
// 401 - Not authenticated
{
  "error": "Authentication required"
}

// 403 - Permission denied
{
  "error": "Permission required: posts.delete"
}

Session Extraction

Middleware automatically extracts session ID from multiple sources:

Priority Order

  1. Header: X-Session-Id
  2. Cookie: session_id
  3. Query Parameter: ?session_id=xxx

Example Requests

bash
# Using header (recommended)
curl -H "X-Session-Id: session_123" https://api.example.com/profile

# Using cookie
curl -b "session_id=session_123" https://api.example.com/profile

# Using query parameter
curl https://api.example.com/profile?session_id=session_123

Combining Middleware

You can combine multiple middleware functions:

typescript
import { Hono } from 'hono';
import { requireAuth, requireUserType, requirePermission } from './lib/auth/middleware';

const app = new Hono();

// Require auth + admin type
app.get('/api/admin/settings', 
  requireAuth(),
  requireUserType('admin'),
  async (c) => {
    return c.json({ settings: await getSettings() });
  }
);

// Require auth + permission
app.post('/api/posts', 
  requireAuth(),
  requirePermission('posts.create'),
  async (c) => {
    const data = await c.req.json();
    return c.json({ post: await createPost(data) });
  }
);

Best Practices

  1. Use requireAuth() for protected routes
  2. Use optionalAuth() for public routes with personalization
  3. Use requireUserType() for role-based access
  4. Use requirePermission() for fine-grained access control
  5. Prefer headers over query parameters for session IDs
  6. Handle errors gracefully with proper error messages

See Also

Released under the MIT License.