REST APIs & Authentication

Modern Rails apps often serve JSON to a frontend or mobile client, and almost all of them need to know who the user is. This lesson covers building APIs and adding authentication.

Learn REST APIs & Authentication in our free Ruby course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Ruby course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end you'll create an API-only controller that renders JSON with proper status codes, store a logged-in user in the session, secure passwords with has_secure_password, and tell authentication from authorization.

What You'll Learn in This Lesson

1️⃣ Building a JSON API

Generate with rails new shop --api for a lean app. Controllers use render json: and communicate results with HTTP status codes — :created (201) for a new record, :unprocessable_entity (422) for validation failures.

2️⃣ Authentication with has_secure_password

has_secure_password hashes passwords with bcrypt into a password_digest column and gives you authenticate . Store the logged-in user's id in the session . Remember: authentication is identity; authorization is permission.

Your turn. Finish an API create action that returns the right JSON and status codes.

Add has_secure_password , build a SessionsController#create , and a current_user helper. Then label which step is authentication and which is authorization.

📋 Quick Reference — APIs & Auth

Practice quiz

Which flag creates a slimmed-down API-only Rails app?

  • rails new shop --json
  • rails new shop --api
  • rails new shop --no-views
  • rails new shop --rest

Answer: rails new shop --api. rails new shop --api generates an API-only app without view layers.

In a controller, how do you return JSON for a record?

  • return @post.json
  • render json: @post
  • respond @post
  • json_out @post

Answer: render json: @post. render json: @post serialises the object to JSON in the response.

Which HTTP status best represents a successfully created resource?

  • 200 OK
  • 201 Created
  • 204 No Content
  • 302 Found

Answer: 201 Created. 201 Created signals a new resource was successfully made.

Which status fits a request that failed model validation?

  • 422 Unprocessable Entity
  • 404 Not Found
  • 500 Internal Server Error
  • 301 Moved Permanently

Answer: 422 Unprocessable Entity. 422 Unprocessable Entity is conventional for validation failures.

What does has_secure_password add to a model?

  • A plaintext password column
  • Two-factor auth
  • A login form
  • password_digest handling, a password= setter, and authenticate

Answer: password_digest handling, a password= setter, and authenticate. has_secure_password manages a bcrypt password_digest plus authenticate.

What column does has_secure_password expect by default?

  • password
  • encrypted_pw
  • password_digest
  • secure_password

Answer: password_digest. It stores the bcrypt hash in a password_digest column.

What is the difference between authentication and authorization?

  • They are the same thing
  • Authentication is who you are; authorization is what you may do
  • Authentication is for APIs only
  • Authorization always happens first

Answer: Authentication is who you are; authorization is what you may do. Authentication verifies identity; authorization decides permitted actions.

In a traditional server-rendered app, where is the logged-in user id usually kept?

  • A query string
  • A global variable
  • The session (a signed cookie)
  • The database id column

Answer: The session (a signed cookie). session[:user_id] is stored in a signed, tamper-resistant cookie.

What is Devise?

  • A testing framework
  • A popular authentication gem for Rails
  • A database adapter
  • A templating engine

Answer: A popular authentication gem for Rails. Devise is a widely used gem that provides ready-made authentication.

Which gem does has_secure_password rely on for hashing?

  • bcrypt
  • openssl-only
  • jwt
  • argon-rails

Answer: bcrypt. has_secure_password uses the bcrypt gem to hash passwords.