{"id":28817701,"url":"https://github.com/rustam-tolipov/rails-api-auth-template","last_synced_at":"2026-04-12T07:34:32.510Z","repository":{"id":298956397,"uuid":"1001617825","full_name":"rustam-tolipov/rails-api-auth-template","owner":"rustam-tolipov","description":"tired of setting up rails api auth from scratch?  me too.  that’s why i built this starter template. so enjoy","archived":false,"fork":false,"pushed_at":"2025-06-13T19:41:34.000Z","size":78,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-13T20:34:34.533Z","etag":null,"topics":["api","authentication","boilerplate","devise","jwt","rails","rspec","ruby","starter-kit"],"latest_commit_sha":null,"homepage":"https://github.com/rustam-tolipov/rails-api-auth-template-v1","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rustam-tolipov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-13T17:36:27.000Z","updated_at":"2025-06-13T19:48:18.000Z","dependencies_parsed_at":"2025-06-13T20:44:55.664Z","dependency_job_id":null,"html_url":"https://github.com/rustam-tolipov/rails-api-auth-template","commit_stats":null,"previous_names":["rustam-tolipov/rails-api-auth-template"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/rustam-tolipov/rails-api-auth-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustam-tolipov%2Frails-api-auth-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustam-tolipov%2Frails-api-auth-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustam-tolipov%2Frails-api-auth-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustam-tolipov%2Frails-api-auth-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rustam-tolipov","download_url":"https://codeload.github.com/rustam-tolipov/rails-api-auth-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rustam-tolipov%2Frails-api-auth-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278881999,"owners_count":26062204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","authentication","boilerplate","devise","jwt","rails","rspec","ruby","starter-kit"],"created_at":"2025-06-18T19:00:46.472Z","updated_at":"2026-04-12T07:34:32.500Z","avatar_url":"https://github.com/rustam-tolipov.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Ruby](https://img.shields.io/badge/ruby-3.3.1-red)\n![Rails](https://img.shields.io/badge/rails-7.2.2.1-red)\n![RSpec](https://img.shields.io/badge/tested%20with-rspec-blue)\n![Swagger](https://img.shields.io/badge/docs-swagger-yellow)\n\n# rails-api-auth-template\n\n\u003e fast start rails api auth setup with devise + jwt\n\n## 🚀 what is this?\n\nthis is a rails 7.2 api-only template with jwt authentication using devise.\nyou can skip the boring setup and jump straight into building cool stuff.\n\n![screenshot](https://github.com/user-attachments/assets/278b23fd-46d0-4085-9170-45a8da140e6f)\n\n## 🧠 why tho?\n\nbecause every time you start a new project, you forget one step.\nor five.\nor all of them.\n\nthis template saves you from:\n\n* repeating the same setup 900 times\n* googling “rails api jwt devise setup” again\n* crying over untracked .env files\n\n## 🔧 stack\n\n* ruby 3.3.1\n* rails 7.2.2.1 (api-only)\n* devise (user auth)\n* jwt (hand-rolled, no devise-jwt dependency)\n* rspec + rswag (for testing + swagger docs)\n* dotenv (for managing secrets)\n* rack-cors (so your frontend doesn’t scream)\n* rack-attack (rate limiting — no room for brute force bots)\n\n## 🧪 how to use this as a template\n\n1. click the green **“Use this template”** button on the top-right\n2. name your new repo (e.g. `my-next-api`)\n3. clone it\n4. run the setup:\n\n```bash\nbundle install\ncp .env.example .env\nrails db:create db:migrate\n```\n\n## ⚙️ or setup as a starter project\n\n```bash\ngit clone https://github.com/yourname/rails-api-auth-template.git\ncd rails-api-auth-template\nbundle install\nyarn install # (if needed)\ncp .env.example .env\nrails db:create db:migrate\n```\n\n## 🔐 auth flow\n\n### signup\n\n```bash\nPOST /api/v1/signup\n{\n  \"email\": \"bob@random.com\",\n  \"password\": \"123456\",\n  \"password_confirmation\": \"123456\"\n}\n```\n\nreturns access token + refresh token + user json\n\n### login\n\n```bash\nPOST /api/v1/login\n{\n  \"email\": \"bob@random.com\",\n  \"password\": \"123456\"\n}\n```\n\nreturns access token + refresh token + user json\n\n### refresh\n\n```bash\nPOST /api/v1/refresh\n{\n  \"refresh_token\": \"\u003cyour_refresh_token\u003e\"\n}\n```\n\nreturns a new access token (keeps you logged in without re-entering credentials)\n\n### profile (protected)\n\n```bash\nGET /api/v1/profile\nAuthorization: Bearer \u003cyour_access_token\u003e\n```\n\nreturns current user\n\n### logout\n\n```bash\nPOST /api/v1/logout\nAuthorization: Bearer \u003cyour_access_token\u003e\n```\n\nblacklists the current token (real logout, token becomes invalid)\n\n## 👥 role-based authorization\n\nusers have roles: `user` (default), `moderator`, or `admin`\n\n### example: admin-only endpoint\n\n```bash\nGET /api/v1/admin/dashboard\nAuthorization: Bearer \u003cadmin_access_token\u003e\n```\n\nreturns admin dashboard data (403 forbidden for non-admins)\n\n### using roles in your controllers\n\n```ruby\nclass MyController \u003c ApplicationController\n  include AuthorizeRequest\n  include AuthorizeRole\n\n  before_action :require_admin  # only admins\n  # or\n  before_action :require_moderator  # admins + moderators\nend\n```\n\n## 🔒 security features\n\n* **no secret fallbacks**: JWT_SECRET_KEY must be set (crashes if missing)\n* **token blacklisting**: logout actually invalidates tokens\n* **refresh tokens**: short-lived access tokens (1 hour) + long-lived refresh tokens (7 days)\n* **rate limiting**: login, signup, and refresh endpoints are throttled\n* **JTI tracking**: every token has a unique identifier for precise control\n* **automatic cleanup**: expired tokens can be cleaned via scheduled jobs\n\n## 📖 swagger ui\n\nrun:\n\n```bash\nRAILS_ENV=test bundle exec rake rswag:specs:swaggerize\nrails s\n```\n\nopen [http://localhost:3000/api-docs](http://localhost:3000/api-docs)\n\n## 🧪 test\n\n```bash\nrspec\n```\n\n## 🚀 production considerations\n\n### cleanup jobs\n\nadd these to your scheduled jobs (sidekiq, cron, etc):\n\n```ruby\n# clean up expired blacklisted tokens\nBlacklistedToken.cleanup_expired\n\n# clean up old refresh tokens\nRefreshToken.cleanup_old_tokens\n```\n\n### environment variables\n\nmake sure to set these in production:\n\n```bash\nJWT_SECRET_KEY=your_super_secret_key_here_use_rails_secret\nDATABASE_URL=your_database_url\nREDIS_URL=your_redis_url (optional, for rack-attack)\n```\n\n### database indexes\n\nmigrations include proper indexes for performance:\n* `blacklisted_tokens.jti` (unique)\n* `blacklisted_tokens.exp`\n* `refresh_tokens.token` (unique)\n* `refresh_tokens.user_id + revoked`\n* `users.role`\n\n## 🤝 contribute\n\nopen to contributions, improvements, or just saying hi.\nopen issues or pull requests.\n\n## ✨ features\n\n* ✅ JWT authentication with secure token generation (includes JTI for tracking)\n* ✅ Token blacklisting for real logout (tokens are invalidated on logout)\n* ✅ Refresh tokens (7-day expiry, keeps users logged in securely)\n* ✅ Role-based authorization (user, moderator, admin roles)\n* ✅ Rate limiting with Rack::Attack (prevents brute force attacks)\n* ✅ Comprehensive test coverage with RSpec\n* ✅ Swagger API documentation via rswag\n* ✅ Security best practices (no fallback secrets, proper validation)\n\n## 🧼 todo\n\n* add email confirmation for signup 📧\n* add password reset functionality 🔑\n* add remember me token (long-lived sessions) 💾\n* add oauth providers (google, github, etc) 🔗\n\n## 📢 shoutout\n\nbuilt to help devs like you (and me) avoid setup fatigue.\nfeel free to fork, star, share, or improve.\n\n## ⚠️ disclaimer\n\nthis template includes production-grade features like token blacklisting, refresh tokens, and role-based auth.\nhowever, you should still:\n* review security settings for your specific use case\n* set up proper monitoring and logging\n* configure ssl/tls in production\n* add email confirmation if needed\n* implement proper error tracking\n\nuse responsibly and test thoroughly before deploying.\n\n---\n\nmade with ♥ by rustam\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustam-tolipov%2Frails-api-auth-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustam-tolipov%2Frails-api-auth-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustam-tolipov%2Frails-api-auth-template/lists"}