![Ruby](https://img.shields.io/badge/ruby-3.3.1-red) ![Rails](https://img.shields.io/badge/rails-7.2.2.1-red) ![RSpec](https://img.shields.io/badge/tested%20with-rspec-blue) ![Swagger](https://img.shields.io/badge/docs-swagger-yellow) # rails-api-auth-template > fast start rails api auth setup with devise + jwt ## πŸš€ what is this? this is a rails 7.2 api-only template with jwt authentication using devise. you can skip the boring setup and jump straight into building cool stuff. ![screenshot](https://github.com/user-attachments/assets/278b23fd-46d0-4085-9170-45a8da140e6f) ## 🧠 why tho? because every time you start a new project, you forget one step. or five. or all of them. this template saves you from: * repeating the same setup 900 times * googling β€œrails api jwt devise setup” again * crying over untracked .env files ## πŸ”§ stack * ruby 3.3.1 * rails 7.2.2.1 (api-only) * devise (user auth) * jwt (hand-rolled, no devise-jwt dependency) * rspec + rswag (for testing + swagger docs) * dotenv (for managing secrets) * rack-cors (so your frontend doesn’t scream) * rack-attack (rate limiting β€” no room for brute force bots) ## πŸ§ͺ how to use this as a template 1. click the green **β€œUse this template”** button on the top-right 2. name your new repo (e.g. `my-next-api`) 3. clone it 4. run the setup: ```bash bundle install cp .env.example .env rails db:create db:migrate ``` ## βš™οΈ or setup as a starter project ```bash git clone https://github.com/yourname/rails-api-auth-template.git cd rails-api-auth-template bundle install yarn install # (if needed) cp .env.example .env rails db:create db:migrate ``` ## πŸ” auth flow ### signup ```bash POST /api/v1/signup { "email": "bob@random.com", "password": "123456", "password_confirmation": "123456" } ``` returns access token + refresh token + user json ### login ```bash POST /api/v1/login { "email": "bob@random.com", "password": "123456" } ``` returns access token + refresh token + user json ### refresh ```bash POST /api/v1/refresh { "refresh_token": "" } ``` returns a new access token (keeps you logged in without re-entering credentials) ### profile (protected) ```bash GET /api/v1/profile Authorization: Bearer ``` returns current user ### logout ```bash POST /api/v1/logout Authorization: Bearer ``` blacklists the current token (real logout, token becomes invalid) ## πŸ‘₯ role-based authorization users have roles: `user` (default), `moderator`, or `admin` ### example: admin-only endpoint ```bash GET /api/v1/admin/dashboard Authorization: Bearer ``` returns admin dashboard data (403 forbidden for non-admins) ### using roles in your controllers ```ruby class MyController < ApplicationController include AuthorizeRequest include AuthorizeRole before_action :require_admin # only admins # or before_action :require_moderator # admins + moderators end ``` ## πŸ”’ security features * **no secret fallbacks**: JWT_SECRET_KEY must be set (crashes if missing) * **token blacklisting**: logout actually invalidates tokens * **refresh tokens**: short-lived access tokens (1 hour) + long-lived refresh tokens (7 days) * **rate limiting**: login, signup, and refresh endpoints are throttled * **JTI tracking**: every token has a unique identifier for precise control * **automatic cleanup**: expired tokens can be cleaned via scheduled jobs ## πŸ“– swagger ui run: ```bash RAILS_ENV=test bundle exec rake rswag:specs:swaggerize rails s ``` open [http://localhost:3000/api-docs](http://localhost:3000/api-docs) ## πŸ§ͺ test ```bash rspec ``` ## πŸš€ production considerations ### cleanup jobs add these to your scheduled jobs (sidekiq, cron, etc): ```ruby # clean up expired blacklisted tokens BlacklistedToken.cleanup_expired # clean up old refresh tokens RefreshToken.cleanup_old_tokens ``` ### environment variables make sure to set these in production: ```bash JWT_SECRET_KEY=your_super_secret_key_here_use_rails_secret DATABASE_URL=your_database_url REDIS_URL=your_redis_url (optional, for rack-attack) ``` ### database indexes migrations include proper indexes for performance: * `blacklisted_tokens.jti` (unique) * `blacklisted_tokens.exp` * `refresh_tokens.token` (unique) * `refresh_tokens.user_id + revoked` * `users.role` ## 🀝 contribute open to contributions, improvements, or just saying hi. open issues or pull requests. ## ✨ features * βœ… JWT authentication with secure token generation (includes JTI for tracking) * βœ… Token blacklisting for real logout (tokens are invalidated on logout) * βœ… Refresh tokens (7-day expiry, keeps users logged in securely) * βœ… Role-based authorization (user, moderator, admin roles) * βœ… Rate limiting with Rack::Attack (prevents brute force attacks) * βœ… Comprehensive test coverage with RSpec * βœ… Swagger API documentation via rswag * βœ… Security best practices (no fallback secrets, proper validation) ## 🧼 todo * add email confirmation for signup πŸ“§ * add password reset functionality πŸ”‘ * add remember me token (long-lived sessions) πŸ’Ύ * add oauth providers (google, github, etc) πŸ”— ## πŸ“’ shoutout built to help devs like you (and me) avoid setup fatigue. feel free to fork, star, share, or improve. ## ⚠️ disclaimer this template includes production-grade features like token blacklisting, refresh tokens, and role-based auth. however, you should still: * review security settings for your specific use case * set up proper monitoring and logging * configure ssl/tls in production * add email confirmation if needed * implement proper error tracking use responsibly and test thoroughly before deploying. --- made with β™₯ by rustam