• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
project logo

tijs

location-feed-generator

This is the Anchor AppView - location based feed generator
Public
Like
1
location-feed-generator
Home
Code
20
.claude
1
.github
1
backend
7
coverage
database
2
debug-oauth-sessions
docs
3
frontend
7
lexicons
2
scripts
2
tests
4
types
1
.gitignore
.vtignore
CLAUDE.md
README.md
deno.json
deno.test.json
H
main.tsx
opinionated-val-town.md
Branches
1
Pull requests
Remixes
History
Environment variables
9
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
docs
/
authentication.md
Code
/
docs
/
authentication.md
Search
…
authentication.md

Authentication

Anchor uses @tijs/atproto-oauth-hono for OAuth authentication with AT Protocol.

Quick Setup

import { createATProtoOAuth, SQLiteStorage, } from "jsr:@tijs/atproto-oauth-hono"; const oauth = createATProtoOAuth({ baseUrl: "https://dropanchor.app", cookieSecret: Deno.env.get("COOKIE_SECRET"), mobileScheme: "anchor-app://auth-callback", appName: "Anchor Location Feed", logoUri: "https://res.cloudinary.com/dru3aznlk/image/upload/v1754747200/anchor-logo-transparent_nrw70y.png", policyUri: "https://dropanchor.app/privacy-policy", sessionTtl: 60 * 60 * 24 * 30, // 30 days for mobile storage: new SQLiteStorage(rawDb), logger: console, }); // Mount OAuth routes app.route("/", oauth.routes);

Configuration

Anchor-Specific Settings

SettingValuePurpose
Base URLhttps://dropanchor.appProduction backend URL
Mobile Schemeanchor-app://auth-callbackiOS app custom URL scheme
Session TTL30 daysExtended for mobile app UX

Environment Variables

  • COOKIE_SECRET - Session encryption key (32+ characters, cryptographically random)
  • ANCHOR_BASE_URL - Override base URL for development

Authentication Methods

All authenticated endpoints support cookie-based authentication:

Cookie: sid=<session-token>

Alternative Bearer token authentication (for compatibility):

Authorization: Bearer <session-token>

Recommended: Use cookie-based authentication. After OAuth, create an HTTPCookie and add it to HTTPCookieStorage (iOS) or document.cookie (web).

Complete OAuth Documentation

For complete OAuth flow details, mobile integration, security considerations, and implementation examples:

📱 Mobile OAuth Guide (Package documentation)

This guide includes:

  • Complete OAuth flow with sequence diagrams
  • All API endpoints with request/response schemas
  • PKCE implementation details
  • Session token format and cookie setup
  • Error handling and recovery strategies
  • iOS Swift and Android Kotlin examples
  • Security best practices

Authenticated API Endpoints

After authentication, use the session cookie to call authenticated endpoints:

Create Check-in

curl -X POST "https://dropanchor.app/api/checkins" \ -b "sid=YOUR_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{"place": {...}, "message": "Great spot!"}'

Delete Check-in

curl -X DELETE "https://dropanchor.app/api/checkins/did:plc:abc/3k2abc" \ -b "sid=YOUR_SESSION_TOKEN"

See API Documentation for complete endpoint reference.

Mobile App Setup

The Anchor iOS app uses ASWebAuthenticationSession for OAuth:

  1. Load OAuth page: /mobile-auth
  2. Complete OAuth: Receive anchor-app://auth-callback?session_token=...
  3. Store token: Save to iOS Keychain
  4. Create cookie: Add to HTTPCookieStorage for URLSession
  5. Make requests: All API calls automatically include cookie

See the Mobile OAuth Guide for implementation details.

Session Management

Session Lifecycle

  • Duration: 30 days
  • Refresh: Automatic via backend
  • Expiration: User must re-authenticate

Session Validation

const session = await oauth.validateSession(request); if (!session.valid) { // User needs to re-authenticate }

Development

Local Testing

For local development, override the base URL:

export ANCHOR_BASE_URL=http://localhost:8000

Testing Authentication

  1. Start the backend: deno task dev
  2. Visit /mobile-auth in browser
  3. Enter test handle: test.bsky.social
  4. Complete OAuth flow

Troubleshooting

Session Invalid/Expired

  • Clear cookies and re-authenticate
  • Check COOKIE_SECRET is set correctly
  • Verify session hasn't exceeded 30-day TTL

Mobile OAuth Not Working

  • Verify mobileScheme matches iOS app URL scheme
  • Check callback URL format: anchor-app://auth-callback
  • Ensure session_token is being stored in Keychain

Token Refresh Issues

  • Backend handles refresh automatically
  • No manual refresh needed for cookie-based auth
  • If refresh fails, user must re-authenticate

Security

  • Session tokens are sealed with Iron Session encryption
  • Cookies use HttpOnly, Secure, and SameSite=Lax flags
  • PKCE protects against authorization code interception
  • DPoP tokens managed entirely on backend
  • No token exposure in mobile app (only sealed session token)

See Security Considerations in the Mobile OAuth Guide.

Additional Resources

  • @tijs/atproto-oauth-hono Package
  • Mobile OAuth Guide
  • AT Protocol OAuth
  • Anchor iOS App Source
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.