Aprenda / Ruby on Rails

FundamentosAula 8 de 2018 min0% da trilha

Autenticação com Devise

Devise resolve senha/sessão/token — entender o que ele gera é melhor do que tratá-lo como caixa-preta.

Autenticação — cadastro, login, hash de senha, reset de senha, confirmação de e-mail — é o tipo de coisa que ninguém deveria reimplementar do zero (é fácil errar de um jeito que vira vulnerabilidade). Devise é a gem padrão do ecossistema Rails pra isso; numa API, ela é combinada com devise-jwt pra emitir token em vez de sessão baseada em cookie.

O que instalar o Devise realmente gera

app/models/usuario.rb
class Usuario < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :validatable,
         :jwt_authenticatable, jwt_revocation_strategy: self
end

Cada símbolo é um módulo que o Devise adiciona: database_authenticatable guarda a senha com hash (nunca em texto puro) e sabe comparar na hora do login; validatable valida formato de e-mail e tamanho mínimo de senha automaticamente; jwt_authenticatable é o que faz a API emitir/validar token JWT em vez de sessão de cookie.

migration gerada — colunas que o Devise precisa
create_table :usuarios do |t|
  t.string :email, null: false, default: ""
  t.string :encrypted_password, null: false, default: ""   # hash da senha, nunca a senha em si
  t.string :reset_password_token
  t.datetime :reset_password_sent_at
  t.timestamps
  t.index :email, unique: true
  t.index :reset_password_token, unique: true
end

encrypted_password nunca guarda a senha original — guarda o resultado de um hash (bcrypt, por padrão). Nem um vazamento do banco de dados expõe a senha em texto puro.

Login numa API — o fluxo com token

POST /login — Resultado
POST /usuarios/sign_in
{ "usuario": { "email": "ana@exemplo.com", "senha": "12345678" } }

# devise-jwt intercepta o login bem-sucedido e devolve o token
# no header Authorization da resposta, não no corpo

Toda requisição seguinte manda esse token de volta no header Authorization; o Devise decodifica e identifica o usuário sem precisar de sessão de servidor guardada em memória — é isso que torna a API stateless, pré-requisito pra escalar horizontalmente sem sticky session.

Quiz rápido

O que a coluna encrypted_password realmente guarda?
Por que autenticação via JWT é considerada 'stateless'?