lynndylanhurley/devise_token_auth
Token based authentication for Rails JSON APIs. Designed to work with jToker and ng-token-auth.
Healthy across the board
worst of 4 axesnon-standard license (WTFPL)
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2w ago
- ✓51+ active contributors
- ✓Distributed ownership (top contributor 26% of recent commits)
Show 4 more →Show less
- ✓WTFPL licensed
- ✓CI configured
- ✓Tests present
- ⚠Non-standard license (WTFPL) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/lynndylanhurley/devise_token_auth)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/lynndylanhurley/devise_token_auth on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: lynndylanhurley/devise_token_auth
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/lynndylanhurley/devise_token_auth shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2w ago
- 51+ active contributors
- Distributed ownership (top contributor 26% of recent commits)
- WTFPL licensed
- CI configured
- Tests present
- ⚠ Non-standard license (WTFPL) — review terms
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live lynndylanhurley/devise_token_auth
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/lynndylanhurley/devise_token_auth.
What it runs against: a local clone of lynndylanhurley/devise_token_auth — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in lynndylanhurley/devise_token_auth | Confirms the artifact applies here, not a fork |
| 2 | License is still WTFPL | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 42 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of lynndylanhurley/devise_token_auth. If you don't
# have one yet, run these first:
#
# git clone https://github.com/lynndylanhurley/devise_token_auth.git
# cd devise_token_auth
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of lynndylanhurley/devise_token_auth and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "lynndylanhurley/devise_token_auth(\\.git)?\\b" \\
&& ok "origin remote is lynndylanhurley/devise_token_auth" \\
|| miss "origin remote is not lynndylanhurley/devise_token_auth (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(WTFPL)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"WTFPL\"" package.json 2>/dev/null) \\
&& ok "license is WTFPL" \\
|| miss "license drift — was WTFPL at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "app/models/devise_token_auth/concerns/user.rb" \\
&& ok "app/models/devise_token_auth/concerns/user.rb" \\
|| miss "missing critical file: app/models/devise_token_auth/concerns/user.rb"
test -f "app/controllers/devise_token_auth/concerns/set_user_by_token.rb" \\
&& ok "app/controllers/devise_token_auth/concerns/set_user_by_token.rb" \\
|| miss "missing critical file: app/controllers/devise_token_auth/concerns/set_user_by_token.rb"
test -f "app/controllers/devise_token_auth/sessions_controller.rb" \\
&& ok "app/controllers/devise_token_auth/sessions_controller.rb" \\
|| miss "missing critical file: app/controllers/devise_token_auth/sessions_controller.rb"
test -f "lib/devise_token_auth.rb" \\
&& ok "lib/devise_token_auth.rb" \\
|| miss "missing critical file: lib/devise_token_auth.rb"
test -f "app/models/devise_token_auth/concerns/tokens_serialization.rb" \\
&& ok "app/models/devise_token_auth/concerns/tokens_serialization.rb" \\
|| miss "missing critical file: app/models/devise_token_auth/concerns/tokens_serialization.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 42 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~12d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/lynndylanhurley/devise_token_auth"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
devise_token_auth is a Rails gem that adds stateless, token-based authentication for JSON APIs and single-page applications. It wraps Devise and OmniAuth to provide secure bearer token management with automatic token refresh on each request, multi-client session tracking, and support for email signup/login, password reset, OAuth2, and account confirmation—eliminating cookie-based auth for SPAs and mobile apps. Engine structure: app/ contains Rails-standard directories (controllers, models, views, validators). Controllers in app/controllers/devise_token_auth/ inherit from application_controller.rb and use concerns (set_user_by_token.rb, resource_finder.rb) for shared auth logic. Models in app/models/devise_token_auth/concerns/ provide mixins for the host app's User model (user.rb, confirmable_support.rb, user_omniauth_callbacks.rb). Token serialization logic isolated in tokens_serialization.rb.
👥Who it's for
Full-stack Rails developers building JSON APIs or SPAs (with AngularJS, Angular, React, Vue, or Flutter frontends) who need production-grade authentication without implementing tokens from scratch. Also relevant to mobile app backend engineers using Rails.
🌱Maturity & risk
Production-ready and actively maintained. The gem has strong test coverage (visible from Code Climate badge in README), CI/CD via GitHub Actions (.github/workflows/test.yml), and multi-language localization (config/locales/ with da-DK.yml, de.yml). Appraisals file indicates testing against multiple Rails versions. No recent commit date given, but the test pipeline and coverage badges suggest ongoing stewardship.
Low-to-moderate risk. Single maintainer (lynndylanhurley) is a known risk factor for OSS longevity. Dependencies are lightweight (Devise and OmniAuth are stable, mature gems), but token auth has security-sensitive code (app/models/devise_token_auth/concerns/) where bugs matter. No visible breaking-change history in CHANGELOG.md snippet, but supporting both ActiveRecord and Mongoid (app/models/devise_token_auth/concerns/{active_record_support,mongoid_support}.rb) adds implementation complexity.
Active areas of work
Cannot determine from provided repo snapshot. No recent commit SHAs, PR list, or milestone data visible. README and CHANGELOG.md are present but not excerpted in full. GitHub Actions workflow file (.github/workflows/test.yml) exists, suggesting CI runs on commits, but current status unknown.
🚀Get running
git clone https://github.com/lynndylanhurley/devise_token_auth.git
cd devise_token_auth
bundle install
bundle exec rake spec
Note: Gemfile present; uses bundler. Rakefile suggests test task available. No explicit Rails app setup needed—this is a gem, not an application.
Daily commands:
This is a gem library, not a runnable app. For development: bundle exec rake spec (inferred from Rakefile presence). For integration testing in a host Rails app: add gem 'devise_token_auth' to Gemfile, run bundle install, then follow devise_token_auth installation guide (likely in docs/ or README).
🗺️Map of the codebase
app/models/devise_token_auth/concerns/user.rb— Core user model concern that defines token generation, validation, and authentication logic—foundational to all authentication flows.app/controllers/devise_token_auth/concerns/set_user_by_token.rb— Request middleware that extracts and validates auth tokens from headers—entry point for every authenticated request.app/controllers/devise_token_auth/sessions_controller.rb— Handles login/logout and token generation—core authentication endpoint that all clients depend on.lib/devise_token_auth.rb— Main gem initialization and configuration loader—sets up all routes, models, and controller overrides.app/models/devise_token_auth/concerns/tokens_serialization.rb— Token storage and retrieval logic for both ActiveRecord and Mongoid—handles persistence across ORM differences.app/controllers/devise_token_auth/registrations_controller.rb— User registration endpoint—critical for onboarding flow and account creation validation.app/controllers/devise_token_auth/token_validations_controller.rb— Token verification endpoint—allows clients to validate token freshness without full re-authentication.
🛠️How to make changes
Add a new authenticated endpoint
- Create a new controller in app/controllers/devise_token_auth/ that inherits from ApplicationController (
app/controllers/devise_token_auth/your_feature_controller.rb) - Include set_user_by_token concern to extract current_user from token (
app/controllers/devise_token_auth/your_feature_controller.rb) - Add route in lib/devise_token_auth/routes.rb under the devise_token_auth scope (
lib/devise_token_auth/routes.rb) - Call authenticate_user! or check current_user in your action to enforce auth (
app/controllers/devise_token_auth/your_feature_controller.rb)
Add support for a new OAuth provider
- Configure the provider in config/initializers/devise_token_auth.rb with client_id and secret (
config/initializers/devise_token_auth.rb) - Omniauth callbacks are routed to omniauth_callbacks_controller via devise—ensure user_omniauth_callbacks is included in user model (
app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb) - Override create or find_or_create_from_auth_hash in omniauth_callbacks_controller if custom mapping needed (
app/controllers/devise_token_auth/omniauth_callbacks_controller.rb)
Add custom validation or behavior to User model
- Include DeviseTokenAuth::Concerns::User in your User model (
app/models/user.rb) - Override or extend methods like valid_password?, create_token, token_is_current? in your User model (
app/models/user.rb) - For ORM-specific logic, check active_record_support or mongoid_support to understand field storage (
app/models/devise_token_auth/concerns/active_record_support.rb)
Customize error responses and i18n messages
- Add or override translations in config/locales/en.yml for your language (
config/locales/en.yml) - Error responses are rendered by controllers—override in your app's devise_token_auth controller (
app/controllers/devise_token_auth/application_controller.rb) - Render JSON responses with custom status codes by overriding render_create_error or similar methods (
app/controllers/devise_token_auth/registrations_controller.rb)
🔧Why these technologies
- Devise (Rails gem) — Provides battle-tested authentication primitives (password hashing, session management, email confirmation) reducing implementation burden for tokens built on top.
- Token-based auth (JWT-like, not strictly JWT) — Enables stateless API authentication for mobile and SPA clients without cookies; allows horizontal scaling without server-side session store.
- Multi-ORM support (ActiveRecord + Mongoid) — Allows adoption in existing Rails projects regardless of database choice; concerns pattern provides clean abstraction.
- Omniauth integration — Delegates OAuth2 provider handling to proven library, reducing security implementation surface while supporting multiple identity providers.
⚖️Trade-offs already made
-
Tokens stored in user model as JSON instead of separate token table
- Why: Simplifies schema and deployment; avoids join query on every request.
- Consequence: Token lookup is O(1) per user but requires parsing JSON; multiple tokens per user (per-device) stored as array—scaling to hundreds of devices per user becomes inefficient.
-
Token expiry and rotation handled at application level, not in the token payload itself
- Why: Gives server full revocation control without issuing new secrets; simpler for logout.
- Consequence: Requires database lookup on every request; cannot be cached or verified offline without callback to server.
-
Includes both 'auth_token' and 'client_id' in token tuple
- Why: Allows server to rotate tokens per device/client without invalidating all sessions globally.
- Consequence: Clients must store and send two values instead of one; adds complexity to client libraries.
-
Uses Devise's email and password mechanics rather than building from scratch
- Why: Reuses password hashing, confirmation emails, password reset flows already battle-tested in Rails.
- Consequence: Couples gem to Devise; not suitable for API-first architectures that don
🪤Traps & gotchas
Token expiry and refresh mechanics: tokens auto-refresh on each request but have short TTL; client must handle the Authorization response header to capture new tokens (non-standard behavior vs stateless JWTs). Multi-client session storage: tokens stored per client/user_agent in a JSON field; requires database support for JSON columns (some databases/ORMs have quirks). OmniAuth redirect handling: omniauth_external_window.html.erb uses postMessage to pass tokens back to parent window—requires specific client-side setup. Devise integration assumptions: code assumes Devise is properly configured in host app; no standalone auth without Devise.
🏗️Architecture
💡Concepts to learn
- Bearer Token Authentication — devise_token_auth's core pattern; stateless auth where client sends Authorization: Bearer <token> header instead of cookies, essential for SPA/mobile API security
- Token Refresh (Sliding Window) — devise_token_auth refreshes tokens on every request with short expiry; client must capture new token from response header to stay authenticated, non-standard vs one-time JWT patterns
- Multi-Client Session Tracking — Unlike traditional sessions, devise_token_auth maintains separate tokens per device/client via tokens_serialization.rb; user can have multiple active sessions (mobile app + web app simultaneously)
- OmniAuth Strategy Pattern — omniauth_callbacks_controller.rb integrates pluggable OAuth providers (Google, GitHub, etc.); understanding how Devise + OmniAuth hooks combine is key to extending auth
- Rails Engine Architecture — devise_token_auth is packaged as an Engine (isolated Rails app within a gem); explains why it has app/, config/, and can be mounted in host apps with minimal configuration
- Concern Mixins (ActiveSupport::Concern) — Heavy use of concerns in app/models/devise_token_auth/concerns/ and app/controllers/devise_token_auth/concerns/ for code reuse; DeviseTokenAuth::Concerns::User is included in host User model
🔗Related repos
lynndylanhurley/ng-token-auth— Official AngularJS client library for devise_token_auth; demonstrates expected token header format and refresh flowneroniaky/angular-token— Modern Angular (2+) client for devise_token_auth; shows how to integrate with contemporary frontend frameworksplataformatec/devise— Foundation gem that devise_token_auth builds on; contains email auth, password reset, and user model logicintridea/omniauth— OAuth2 orchestration layer; devise_token_auth's omniauth_callbacks_controller.rb delegates to OmniAuth strategiesjwt/ruby-jwt— Token encoding/decoding; likely used under the hood for token serialization (inferred from tokens_serialization.rb name)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for Mongoid support in user model concerns
The repo has app/models/devise_token_auth/concerns/mongoid_support.rb but based on the file structure, there's likely insufficient test coverage for Mongoid-specific functionality (token serialization, user callbacks, etc.). This is critical since devise_token_auth supports both ActiveRecord and Mongoid, and Mongoid users deserve parity. New contributors can add dedicated test suite for Mongoid operations without affecting AR tests.
- [ ] Create spec/models/devise_token_auth/concerns/mongoid_support_spec.rb for Mongoid-specific token operations
- [ ] Add tests in spec/models/devise_token_auth/concerns/tokens_serialization_spec.rb for Mongoid serialization edge cases
- [ ] Verify test.yml CI workflow runs Mongoid tests separately (may require Appraisals gemfile for Mongoid variant)
- [ ] Document Mongoid testing setup in .github/CONTRIBUTING.md
Add integration tests for OmniAuth callback flow with token generation
The repo has app/controllers/devise_token_auth/omniauth_callbacks_controller.rb and app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb but lacks visible E2E tests validating the complete OmniAuth → token generation → response flow. This is a high-risk integration that benefits from explicit test coverage to catch edge cases around token validation, user creation, and state transitions.
- [ ] Create spec/controllers/devise_token_auth/omniauth_callbacks_controller_spec.rb with full flow tests (successful auth, user creation, token response)
- [ ] Add spec/requests/omniauth_integration_spec.rb for realistic HTTP request/response cycles with multiple providers
- [ ] Test edge cases: existing user re-authentication, email mismatch handling, user_omniauth_callbacks concern behavior
- [ ] Update .github/workflows/test.yml if new env vars (OAuth test credentials) are needed
Create integration test suite for email validator and confirmation flow
The repo has app/validators/devise_token_auth_email_validator.rb and app/controllers/devise_token_auth/confirmations_controller.rb plus 16 localization files, but no visible test for the complete registration → confirmation → validation flow across different locales. This is valuable for ensuring email validation rules apply consistently during signup and token issuance, and catching i18n bugs.
- [ ] Create spec/validators/devise_token_auth_email_validator_spec.rb testing edge cases (unicode emails, subdomains, RFC compliance)
- [ ] Create spec/requests/confirmations_integration_spec.rb testing: registration with confirmation required, confirmation token validation, expired token handling, resend logic
- [ ] Add parametrized tests in confirmations spec to validate error messages for at least 3 locales (en, de, ja) from config/locales/
- [ ] Ensure tests validate that invalid emails are rejected before token generation (security boundary test)
🌿Good first issues
- Add test coverage and docs for app/validators/devise_token_auth_email_validator.rb—currently isolated with no visible test file or usage example in app/controllers/
- Expand app/views/devise/mailer/ email templates: confirmation_instructions, reset_password_instructions, and unlock_instructions are present but likely lack comprehensive i18n coverage for all locales in config/locales/
- Improve resource_finder.rb concern: add comprehensive specs and docs for how it resolves User models in multi-model setups (likely underdocumented given support for 'multiple user models' mentioned in README)
⭐Top contributors
Click to expand
Top contributors
- @MaicolBen — 26 commits
- @hatsu38 — 7 commits
- @dependabot[bot] — 3 commits
- @jotolo — 3 commits
- @lynndylanhurley — 3 commits
📝Recent commits
Click to expand
Recent commits
bcdc3a5— Update devise to 5 (#1675) (MaicolBen)02f1117— ci: Add support ruby 3.3, 3.4 (#1669) (hatsu38)273eac7— ci: update CI dependencies (actions, postgres, mongodb) (#1670) (hatsu38)0b3995d— Fix mongo dependency test suite (#1668) (MaicolBen)ba7198e— chore: update rails dependency from 8.1 to 8.2 (#1666) (hatsu38)3c32d15— Handle expired reset_password_tokens on passwords#update (#1662) (catks)9719d24— feat: enforce token lifespan limit when cleaning old tokens (#1657) (leightjohnson93)64096bd— Fix, Use devise_will_save_change_to_email? method for email change detection (#1654) (hnegishi)c5109f7— Add flutter_token_auth to Readme (#1655) (diarmuidr3d)74ec935— Modify the edit method in PasswordsController to include reset_password_token in the redirect URL. (#1650) (kaekasui)
🔒Security observations
- High · Token-Based Authentication Requires Secure Transport —
app/controllers/devise_token_auth/concerns/set_user_by_token.rb. devise_token_auth implements token-based authentication for JSON APIs. If HTTPS is not enforced, tokens can be intercepted in transit, compromising authentication security. Fix: Enforce HTTPS in production. Configure Rails withconfig.force_ssl = trueand ensure secure cookie flags are set. Document HTTPS requirement in security guide. - High · Token Storage and Expiration Management —
app/models/devise_token_auth/concerns/tokens_serialization.rb. The gem stores authentication tokens (likely in Authorization headers or cookies). Without proper token expiration and rotation policies, compromised tokens could provide indefinite access. Fix: Implement short token expiration times, token rotation on refresh, and revocation mechanisms. Ensure tokens are cryptographically secure and use proper hashing algorithms. - High · CORS Configuration Risk —
docs/config/cors.md. Token-based authentication in JSON APIs is vulnerable to CORS misconfiguration. Overly permissive CORS settings could allow unauthorized cross-origin token access. Fix: Review and restrict CORS origins to trusted domains only. Avoid using wildcard '*' for CORS origins. Document recommended CORS configuration securely. - Medium · Email Validation May Be Insufficient —
app/validators/devise_token_auth_email_validator.rb. Custom email validator present (app/validators/devise_token_auth_email_validator.rb) could have gaps in validation that allow malformed or malicious email addresses. Fix: Ensure email validation follows RFC 5322 standards. Implement email verification/confirmation flow and validate both format and deliverability. - Medium · OmniAuth Integration Security —
app/controllers/devise_token_auth/omniauth_callbacks_controller.rb. OmniAuth callbacks controller (omniauth_callbacks_controller.rb) handles external authentication. Misconfigured OAuth provider verification could allow account takeover. Fix: Verify OmniAuth provider configuration requires state parameter validation. Ensure provider keys/secrets are stored as environment variables, never hardcoded. Validate all provider responses. - Medium · Password Reset Token Exposure Risk —
app/controllers/devise_token_auth/passwords_controller.rb, app/views/devise/mailer/reset_password_instructions.html.erb. Password reset functionality (passwords_controller.rb, reset_password_instructions.html.erb) requires secure token generation and delivery. Fix: Ensure password reset tokens are cryptographically random, time-limited (15-30 minutes), single-use, and sent over HTTPS only. Implement rate limiting on password reset requests. - Medium · Confirmation Token Security —
app/controllers/devise_token_auth/confirmations_controller.rb. Email confirmation tokens (confirmations_controller.rb) must be properly secured to prevent unauthorized account confirmation. Fix: Use cryptographically random tokens, implement expiration windows, enforce single-use tokens, and rate limit confirmation attempts. - Medium · Account Unlock Mechanism Security —
app/controllers/devise_token_auth/unlocks_controller.rb. Account unlock functionality (unlocks_controller.rb) could be abused if unlock tokens are not properly secured. Fix: Implement time-limited, cryptographically random unlock tokens. Rate limit unlock requests and require additional verification steps. - Medium · Missing Security Headers Documentation —
docs/security.md. No evidence of security headers documentation (CSP, X-Frame-Options, X-Content-Type-Options) in provided files. Fix: Document recommended security headers: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Strict-Transport-Security. - Low · Resource Finder Implementation Review —
app/controllers. Resource finder concern (resource_finder.rb) queries user resources. Improper implementation could lead to information disclosure or privilege escalation. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.