bin/rails generate authentication: o gerador do Rails 8
Um comando que vem com o Rails deste app
O bin/rails generate authentication vem dentro do railties-8.1.3.1, a versão do Rails que este app usa, e o arquivo USAGE dele diz o que ele faz:
Description:
Generates a basic authentication system with users, sessions, and password reset.
Example:
`bin/rails generate authentication`
Rodado num app Rails 8 novo, ele produz um sistema de login que funciona: um model User, um model Session, um controller, um concern que qualquer outro controller pode incluir, mailers de troca de senha, e as rotas e migrations por trás de tudo. Todo arquivo que este curso descreve vem dos templates instalados do gerador, citados em vez de parafraseados.
O que o create_authentication_files gera
O código do gerador, authentication_generator.rb:
def create_authentication_files
template "app/models/session.rb"
template "app/models/user.rb"
template "app/models/current.rb"
template "app/controllers/sessions_controller.rb"
template "app/controllers/concerns/authentication.rb"
template "app/controllers/passwords_controller.rb"
template "app/channels/application_cable/connection.rb" if defined?(ActionCable::Engine)
if defined?(ActionMailer::Railtie)
template "app/mailers/passwords_mailer.rb"
template "app/views/passwords_mailer/reset.html.erb"
template "app/views/passwords_mailer/reset.text.erb"
end
end
Seis arquivos no mínimo, mais se o app carregar Action Cable ou Action Mailer (a maioria dos apps Rails 8 carrega os dois por padrão, então na prática costumam ser todos). As duas próximas aulas leem os quatro que mais importam para o login: o concern Authentication, o Current, o Session e o SessionsController.
As rotas e migrations que ele acrescenta
Mesmo gerador, mesmo arquivo:
def configure_authentication_routes
route "resources :passwords, param: :token"
route "resource :session"
end
def add_migrations
generate "migration", "CreateUsers", "email_address:string!:uniq password_digest:string!", "--force"
generate "migration", "CreateSessions", "user:references ip_address:string user_agent:string", "--force"
end
Duas migrations. users ganha um email_address obrigatório e único e um password_digest, a coluna em que o has_secure_password grava hashes BCrypt. sessions ganha uma chave estrangeira user_id para o belongs_to, mais ip_address e user_agent, então cada login é um registro que dá para inspecionar, não só um id.
O bcrypt, tratado de qualquer jeito
def enable_bcrypt
if File.read(File.expand_path("Gemfile", destination_root)).include?('gem "bcrypt"')
uncomment_lines "Gemfile", /gem "bcrypt"/
bundle_command("install --quiet")
else
bundle_command("add bcrypt", {}, quiet: true)
end
end
Um app novo do rails new vem com gem "bcrypt" comentado no Gemfile; o BCrypt é a gem de hash de senha que o Rails recomenda. O gerador descomenta a linha se ela existir, ou acrescenta a gem se não existir. De qualquer jeito, o has_secure_password, de que todo arquivo deste curso depende, tem o BCrypt disponível.
O que este curso cobre
Sete aulas, conferidas no Rails instalado deste app e no código feito à mão dele. A aula 2 trata do concern do gerador, do Current e do model Session. A aula 3 trata do SessionsController e de dois recursos do Rails 8 citados do código instalado, User.authenticate_by e a DSL rate_limit de controller. A aula 4 trata do sistema próprio deste app, diferente: Identity::User, Identity::Current e Auth::SessionsController. A aula 5 trata do Auth::AuthenticateUserService e das escolhas de segurança nele. A aula 6 compara o que cada sistema tem e não tem. A aula 7 junta tudo, com um pequeno desafio em Ruby baseado na lógica de bloqueio deste app.
Este app não rodou esse gerador. As próximas aulas mostram o que ele construiu no lugar, e por que é uma escolha de engenharia diferente, não pior.
Continue com a aula 2
O concern gerado, o Current e uma sessão no banco
Como o concern gerado protege toda ação por padrão, e como o Current e uma linha Session registram logins.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.