248 lines
5.6 KiB
Markdown
248 lines
5.6 KiB
Markdown

|
||

|
||

|
||

|
||
|
||
# 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.
|
||
|
||

|
||
|
||
## 🧠 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": "<your_refresh_token>"
|
||
}
|
||
```
|
||
|
||
returns a new access token (keeps you logged in without re-entering credentials)
|
||
|
||
### profile (protected)
|
||
|
||
```bash
|
||
GET /api/v1/profile
|
||
Authorization: Bearer <your_access_token>
|
||
```
|
||
|
||
returns current user
|
||
|
||
### logout
|
||
|
||
```bash
|
||
POST /api/v1/logout
|
||
Authorization: Bearer <your_access_token>
|
||
```
|
||
|
||
retires 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 <admin_access_token>
|
||
```
|
||
|
||
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 retireing**: 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 retired tokens
|
||
RetiredToken.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:
|
||
* `retired_tokens.jti` (unique)
|
||
* `retired_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 retireing 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 retireing, 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
|