Sequelize é um ORM Node.js baseado em promessa. Pode ser usado com PostgreSQL, MySQL, MariaDB, SQLite e MSSQL. Neste tutorial, estaremos implementando a autenticação para usuários de um aplicativo da web. E usaremos o Passport, o middleware de autenticação popular para Node, junto com Sequelize e MySQL para implementar o registro e login do usuário.
Primeiros passos
Certifique-se de ter o seguinte instalado em sua máquina:
- Nó
- MySQL
Para este tutorial, usaremos o Node.js junto com o Express, então vamos em frente e começamos a instalar o que precisamos.
Etapa 1:gerar um arquivo package.json
Crie um diretório para seu aplicativo. Dentro deste diretório, execute isso no seu terminal ou prompt de comando:
npm init
Isso inicializa o npm Dependency Manager. Isso apresentará uma série de prompts pelos quais passaremos rapidamente.
- Digite o nome do seu aplicativo sem espaços e pressione Enter para 'nome'.
- Pressione Enter para a 'versão'.
- Para 'description', neste tutorial, digitaremos "Using Passport with Sequelize and MySQL" como uma descrição e pressionaremos Enter. Isso também pode ficar em branco.
- Para 'ponto de entrada (index.js)', digite server.js e pressione Enter.
- Para 'comando de teste', pressione Enter.
- Para 'git repository', você pode inserir o repositório git onde seu aplicativo reside, se você tiver um, ou apenas pressionar Enter para deixar em branco.
- Para 'Palavras-chave', pressione Enter.
- Para 'autor', pressione Enter ou digite seu nome antes de fazer isso.
- Para 'licença', pressione Enter.
- Para '(Is this okay )', isso mostra a aparência do seu package.json. Digite Sim e pressione Enter.
Etapa 2:instalar dependências
As principais dependências para este tutorial são:
- Expresso
- Sequelizar
- MySQL
- Passaporte
- Estratégia local do passaporte
- Analisador de corpo
- Sessão Expressa
- Bcrypt Nodejs
- Express Handlebars para as visualizações
Para instalá-los, a partir do seu terminal ou prompt de comando, execute o seguinte um após o outro.
npm install express --savenpm install sequelize --savenpm install mysql --savenpm install passaporte --savenpm install passaporte-local --savenpm install body-parser --savenpm install express-session --savenpm install bcrypt-nodejs - -savenpm instalar express-handlebars --save
Se você estiver usando o Git para este projeto:
Na pasta do seu projeto crie um arquivo .gitignore.
Adicione esta linha ao arquivo .gitignore.
node_modules
Etapa 3:configurar o aplicativo
Agora, criamos um arquivo de servidor. Este será o arquivo principal chamado quando você digitar o seguinte:
npm start
Isso executa o aplicativo. Você também pode executar o aplicativo digitando node server.js.
servidor de nó.js
Então, em nossa pasta de projeto, criamos um novo arquivo e nomeamos este arquivo server.js .
Dentro do server.js arquivo, colamos o seguinte:
var express =require('express');var app =express();app.get('/', function(req, res) { res.send('Welcome to Passport with Sequelize');});app.listen(5000, function(err) { if (!err) console.log("Site está ativo"); else console.log(err)});
A primeira linha atribui o módulo express a uma variável express. Em seguida, inicializamos o express e o nomeamos uma variável:app.
Em seguida, fazemos o aplicativo escutar na porta 5000 . Você pode escolher qualquer número de porta livre em seu computador.
Em seguida, chamamos o
app.get()
função de roteamento expresso para responder com "Welcome to Passport with Sequelize" quando uma solicitação GET é feita para "/". Para testar no seu computador, execute-o dentro da pasta do seu projeto:
servidor de nó.js
Se você vir o texto "Welcome to Passport with Sequelize" quando visitar http://localhost:5000/ então parabéns! Caso contrário, verifique se você fez tudo exatamente como está escrito acima.
Em seguida, importamos alguns módulos necessários, como passaporte, sessão expressa e analisador de corpo.
Após
var app = express()
adicionamos as seguintes linhas:var passaporte =require('passport')var session =require('express-session')var bodyParser =require('body-parser')
Nas duas primeiras linhas, importamos o módulo de passaporte e a sessão expressa, os quais precisamos lidar com a autenticação.
Em seguida, importamos o módulo body-parser. Isso extrai toda a parte do corpo de uma solicitação recebida e a expõe em um formato mais fácil de trabalhar. Neste caso, usaremos o formato JSON.
Para permitir que nosso aplicativo use o analisador de corpo, adicionamos essas linhas alguns espaços abaixo das linhas de importação:
//For BodyParserapp.use(bodyParser.urlencoded({ extended:true }));app.use(bodyParser.json());
Em seguida, inicializamos o passaporte e a sessão expressa e a sessão do passaporte e adicionamos ambas como middleware. Fazemos isso adicionando essas linhas alguns espaços após a linha de importação bodyParser.
// Para Passportapp.use(session({ secret:'keyboard cat',resave:true, saveUninitialized:true})); // session secretapp.use(passport.initialize());app.use(passport.session()); // sessões de login persistentes
Vamos começar a trabalhar na autenticação real agora.
Faremos isso em quatro etapas:
- Configure o Sequelize com MySQL.
- Crie o modelo de usuário.
- Configure visualizações.
- Escreva uma estratégia de passaporte.
1. Configurar Sequelizar com MySQL
Primeiro, criamos um banco de dados no MySQL. Dê-lhe o seu nome preferido. Para este tutorial, vamos criar um banco de dados chamado
sequelize_passport
em MySQL. Em seguida, configuramos a configuração para lidar com os detalhes do banco de dados.
Primeiro, vamos importar o módulo dot-env para lidar com variáveis de ambiente.
Execute isso na pasta do projeto raiz:
npm install --save dotenv
Em seguida, importamos no arquivo principal do servidor, server.js, logo abaixo das outras importações.
var env =require('dotenv').load();
Em seguida, criamos um arquivo em nossa pasta de projeto e o nomeamos .env.
Este próximo passo a seguir é opcional se você não estiver usando o Git:
Adicionaremos o arquivo .env ao seu arquivo .gitignore.
Seu arquivo .gitignore deve ficar assim:
node_modules.env
Depois disso, adicionamos nosso ambiente ao arquivo .env adicionando esta linha:
NODE_ENV='development'
Em seguida, criamos um arquivo config.json que será usado pelo Sequelize para gerenciar diferentes ambientes.
A primeira coisa a fazer é criar uma pasta chamada
config
em nossa pasta de projeto. Dentro desta pasta, criamos um config. json Arquivo. Este arquivo deve ser ignorado se você estiver enviando para um repositório. Para fazer isso, adicione o seguinte código ao seu .gitignore:config/config.json
Em seguida, colamos o seguinte código em nosso arquivo config.json.
{ "desenvolvimento":{ "username":"root", "password":null, "database":"sequelize_passport", "host":"127.0.0.1", "dialect":"mysql" }, "test":{ "username":"", "password":null, "database":"", "host":"", "dialect":"mysql" }, "production":{ "username":"", "password":null, "database":"", "host":"127.0.0.1", "dialect":"mysql" }}
Lembre-se de substituir os valores no bloco de desenvolvimento acima pelos detalhes de autenticação do banco de dados.
Em seguida, instalamos o sequelize com npm. Para fazer isso, execute o seguinte comando na pasta raiz do projeto:
npm install --save sequelize
Agora é hora de criar os modelos pasta.
Primeiro, criamos um diretório chamado
app
em nossa pasta de projeto. Dentro do aplicativo pasta, criamos uma nova pasta chamadamodels e crie um novo arquivo chamado index.js nos modelos pasta.
Dentro do arquivo index.js, colamos o código abaixo.
"use strict";var fs =require("fs");var path =require("path");var Sequelize =require("sequelize");var env =process.env.NODE_ENV || "development";var config =require(path.join(__dirname, '..', 'config', 'config.json'))[env];var sequelize =new Sequelize(config.database, config.username, config .password, config);var db ={};fs .readdirSync(__dirname) .filter(function(file) { return (file.indexOf(".") !==0) &&(file !=="index. js"); }) .forEach(function(file) { var model =sequelize.import(path.join(__dirname, file)); db[model.name] =model; });Object.keys(db). forEach(function(modelName) { if ("associado" em db[modelName]) { db[modelName].associate(db); }});db.sequelize =sequelize;db.Sequelize =Sequelize;module.exports =db;
Este arquivo é usado para importar todos os modelos que colocamos nos modelos pasta e exportá-los.
Para testar se está tudo bem, adicionamos isso em nosso arquivo server.js.
//Modelsvar models =require("./app/models");//Sync Databasemodels.sequelize.sync().then(function() { console.log('Bom! O banco de dados parece bom')}) .catch(function(err) { console.log(err, "Algo deu errado com a atualização do banco de dados!")});
Aqui, estamos importando os modelos e, em seguida, chamando a função de sincronização Sequelize.
Execute isso para ver se está tudo bem:
servidor de nó.js
Se você receber a mensagem "O site está ativo! O banco de dados parece bom", então você configurou o Sequelize com sucesso.
Caso contrário, siga cuidadosamente as etapas acima e tente depurar o problema com ajuda.
2. Crie o modelo de usuário
A próxima coisa que vamos fazer é criar o modelo de usuário, que é basicamente a tabela de usuários. Isso conterá informações básicas do usuário.
Em nossos modelos pasta, criamos um arquivo e o nomeamos user.js . O caminho completo para este arquivo deve ser app/models/user.js.
Abra o arquivo user.js e adicione o seguinte código:
module.exports =function(sequelize, Sequelize) { var User =sequelize.define('user', { id:{ autoIncrement:true, primaryKey:true, type:Sequelize.INTEGER }, firstname:{ type:Sequelize .STRING, notEmpty:true }, sobrenome:{ type:Sequelize.STRING, notEmpty:true }, nome de usuário:{ type:Sequelize.TEXT }, sobre:{ type:Sequelize.TEXT }, email:{ type:Sequelize.STRING , validate:{ isEmail:true } }, senha:{ type:Sequelize.STRING, allowNull:false }, last_login:{ type:Sequelize.DATE }, status:{ type:Sequelize.ENUM('active', 'inactive' ), defaultValue:'ativo' } }); retornar Usuário;}
Agora execute:
servidor de nó.js
Você deve ver o familiar "O site está ativo. Legal! Banco de dados parece bom. ". Isso significa que nossos modelos de Sequelize foram sincronizados com sucesso e, se você verificar seu banco de dados, verá uma tabela de usuários com as colunas especificadas presentes.
3:configurar visualizações
Primeiro, vamos criar a visualização para inscrição e conectá-la.
A primeira coisa a fazer é importar o módulo express handlebars que usamos para visualizações neste tutorial.
Adicione esta linha ao arquivo inicial principal, server.js.
var exphbs = require('express-handlebars')
Seu bloco de importação deve ficar assim neste momento.
var express =require('express')var app =express()var passaporte =require('passport')var session =require('express-session')var bodyParser =require('body-parser')var env =require('dotenv').load()var exphbs =require('express-handlebars')
Em seguida, adicionamos as seguintes linhas em nosso arquivo server.js.
//For Handlebarsapp.set('views', './app/views')app.engine('hbs', exphbs({ extname:'.hbs'}));app.set('view engine ', '.hbs');
Agora, em nossa pasta app, criamos três pastas chamadas views, controladores, e rotas .
Na pasta views, criamos um arquivo chamado signup. hbs e cole o código abaixo nele.
Em seguida, em nossos controladores pasta, criamos um novo arquivo e o nomeamos authcontroller.js.
Neste arquivo, colamos o seguinte controller para a rota de inscrição que criaremos em um momento.
var export =module.exports ={}exports.signup =function(req, res) { res.render('signup');}
Em seguida, criamos uma rota para inscrição. Na pasta de rotas, criamos um novo arquivo chamado auth.js e, neste arquivo, importamos o controlador de autenticação e definimos a rota de inscrição.
var authController =require('../controllers/authcontroller.js');module.exports =function(app) { app.get('/signup', authController.signup);}
Agora, vamos importar essa rota em nosso server.js e passar app como argumento.
No servidor, após a importação dos modelos, adicione estas linhas:
//Routesvar authRoute =require('./app/routes/auth.js')(app);
Rode isto:
servidor de nó.js
Agora, visite http://localhost:5000/signup e você verá o formulário de inscrição.
Vamos repetir as etapas para o formulário de entrada. Como antes, criaremos um arquivo chamado signin.hbs em nossa pasta views e cole o seguinte código HTML nela:
Em seguida, adicione um controlador para o login em app/controllers/authcontroller.js.
exports.signin =function(req, res) { res.render('signin');}
Em seguida, em app/routes/auth.js , adicionamos uma rota para login como esta:
app.get('/signin', authController.signin);
Agora quando você executa:
node server.js
e visite http://localhost:5000/signin/, você deverá ver o formulário de login.
O passo final e principal é escrever nossas estratégias de passaporte.
4. Escreva uma estratégia de passaporte
Em app/config , criamos uma nova pasta chamada passport.
Então, em nossa nova pasta app/config/passport, criamos um novo arquivo e o nomeamos passport.js . Este arquivo conterá nossas estratégias de passaporte.
Em passport.js , usaremos o modelo de usuário e o passaporte.
Primeiro, importamos bcrypt que precisamos para proteger as senhas.
var bCrypt = require('bcrypt-nodejs');
Em seguida, adicionamos um bloco module.exports como este:
module.exports =function(passaporte, usuário) {}
Dentro deste bloco, inicializamos a estratégia local do passaporte, e o modelo do usuário, que será passado como argumento. Veja como fazemos isso:
module.exports =function(passaporte, usuário) { var Usuário =usuário; var LocalStrategy =require('passport-local').Strategy;}
Em seguida, definimos nossa estratégia personalizada com nossa instância do LocalStrategy assim:
passport.use('local-signup', new LocalStrategy( { usernameField:'email', passwordField:'password', passReqToCallback:true // nos permite passar toda a requisição para o callback },));
Agora declaramos qual solicitação (req ) são os campos usernameField e passwordField (variáveis de passaporte).
A última variável passReqToCallback nos permite passar toda a solicitação para o retorno de chamada, o que é particularmente útil para se inscrever.
Após a última vírgula, adicionamos esta função de retorno de chamada.
função(req, email, password, done) { }
Nesta função, trataremos de armazenar os detalhes de um usuário.
Primeiro, adicionamos nossa função de geração de senha com hash dentro da função de retorno de chamada.
var generateHash =function(senha) { return bCrypt.hashSync(senha, bCrypt.genSaltSync(8), null); };
Em seguida, usando o modelo de usuário Sequelize que inicializamos anteriormente como Usuário , verificamos se o usuário já existe e, se não, adicionamos.
User.findOne({ where:{ email:email }}).then(function(user) { if (user) { return done(null, false, { message:'Esse email já foi recebido' }); } else { var userPassword =generateHash(password); var data ={ email:email, password:userPassword, firstname:req.body.firstname, lastname:req.body.lastname }; User.create(data).then(function (newUser, created) { if (!newUser) { return done(null, false); } if (newUser) { return done(null, newUser); } }); }});
User.create()
é um método Sequelize para adicionar novas entradas ao banco de dados. Observe que os valores nos dados objeto são obtidos do req.body objeto que contém a entrada do nosso formulário de inscrição. Seu passaporte.js deve ficar assim:
//load bcryptvar bCrypt =require('bcrypt-nodejs');module.exports =function(passport, user) { var User =user; var LocalStrategy =require('passport-local').Strategy; passaporte.use('local-signup', new LocalStrategy( { usernameField:'email', passwordField:'password', passReqToCallback:true // nos permite passar de volta toda a solicitação para o callback }, function(req, email, password, done) { var generateHash =function(password) { return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null); }; User.findOne({ where:{ email:email } }).then(function (usuário) { if (usuário) { return done(null, false, { message:'Esse email já foi recebido' }); } else { var userPassword =generateHash(password); var data ={ email:email, password:senha do usuário, nome:req.body.firstname, sobrenome:req.body.lastname }; User.create(data).then(function(newUser, created) { if (!newUser) { return done(null, false); } if (newUser) { return done(null, newUser); } }); } }); } ));}
Agora vamos importar a estratégia em server.js.
Para fazer isso, adicionamos essas linhas abaixo da importação de rotas em server.js.
//carregar estratégias de passaporterequire('./app/config/passport/passport.js')(passport, models.user);
Seu server.js deve estar assim neste momento:
var express =require('express')var app =express()var passaporte =require('passport')var session =require('express-session')var bodyParser =require('body-parser')var env =require('dotenv').load()var exphbs =require('express-handlebars')//For BodyParserapp.use(bodyParser.urlencoded({ extended:true}));app.use(bodyParser.json( ));// Para Passportapp.use(session({ secret:'keyboard cat', resave:true, saveUninitialized:true})); // session secretapp.use(passport.initialize());app.use(passport.session()); // sessões de login persistentes//For Handlebarsapp.set('views', './app/views')app.engine('hbs', exphbs({ extname:'.hbs'}));app.set(' view engine', '.hbs');app.get('/', function(req, res) { res.send('Welcome to Passport with Sequelize');});//Modelsvar models =require(". /app/models");//Routesvar authRoute =require('./app/routes/auth.js')(app);//carregar estratégias de passaporterequire('./app/config/passport/passport.js') (passport, models.user);//Sync Databasemodels.sequelize.sync().then(function() { console.log('Bom! O banco de dados parece bom')}).catch(function(err) { console.log (err, "Algo deu errado com a atualização do banco de dados!")});app.listen(5000, function(err) { if (!err) console.log("Site está ativo"); else console.log(err )});
Agora vamos aplicar a estratégia ao nosso /signup rota.
Veja como fazemos isso:
Primeiro, vamos para app/routes/auth.js , e adicione uma rota para postagem para inscrição como esta.
app.post('/signup', passaporte.authenticate('local-signup', { successRedirect:'/dashboard', failureRedirect:'/signup' }));
Como precisamos de passaporte, precisamos passá-lo para esse método. Podemos importar o passaporte neste script ou passá-lo do server.js. Vamos fazer o último.
Modifique a função exportada neste arquivo app/routes/auth.js ter o passaporte como parâmetro. O código em app/routes/auth.js deve ficar assim após a modificação.
var authController =require('../controllers/authcontroller.js');module.exports =function(app, passaporte) { app.get('/signup', authController.signup); app.get('/signin', authController.signin); app.post('/signup', passaporte.authenticate('local-signup', { successRedirect:'/dashboard', failureRedirect:'/signup' } ));}
Em seguida, em server.js , modificamos a importação de rotas e adicionamos o passaporte como um argumento assim:
var authRoute = require('./app/routes/auth.js')(app,passport);
Agora, acesse o URL de inscrição http://localhost:5000/signup/ e tente se inscrever.
Ao tentar se inscrever, você receberá um erro "Falha ao serializar o usuário na sessão ". Isso ocorre porque o passaporte precisa salvar um ID de usuário na sessão e o usa para gerenciar a recuperação dos detalhes do usuário quando necessário.
Para resolver isso, vamos implementar as funções serializar e desserializar do passaporte em nosso app/config/passport/passport.js Arquivo.
Primeiro, adicionamos a função serialize. Nesta função, salvaremos o id do usuário à sessão.
Para fazer isso, adicionamos as seguintes linhas abaixo da inicialização da estratégia local.
//serializepassport.serializeUser(function(user, done) { done(null, user.id);});
Em seguida, implementamos a função desserialize. Adicione a função logo abaixo da função serialize.
// desserializar o passaporte do usuário.deserializeUser(function(id, done) { User.findById(id).then(function(user) { if (user) { done(null, user.get()); } else { done(user.errors, null); } });});
Na função desserialize acima, usamos o Sequelize
findById
promessa de obter o usuário e, se for bem-sucedida, uma instância do modelo Sequelize será retornada. Para obter o objeto User desta instância, usamos a função Sequelize getter assim:user.get()
. Agora execute novamente:
servidor de nó.js
E tente se inscrever. Viva se você recebeu o "Não é possível obter / painel"! Isso significa que nossa autenticação foi bem-sucedida. Lembre-se de que redirecionamos para /dashboard em nosso método passaporte.authenticate em routes/auth.js .
Agora vamos em frente e adicionar essa rota. Em seguida, adicione um middleware para garantir que a página só possa ser acessada quando um usuário estiver conectado à sessão.
Em nosso aplicativo/visualizações pasta, criamos um novo arquivo chamado dashboard.hbs e adicione o seguinte código HTML nele.
Passaporte com Sequelização Painel
Viva! você está logado.
Em routes/auth.js , adicionamos esta linha dentro de module.exports quadra:
app.get('/dashboard',authController.dashboard);
Em seguida, vamos para app/controllers/authController.js e adicione o controlador do painel.
exports.dashboard =function(req, res) { res.render('dashboard');}
Seu AuthController.js deve ficar assim:
var export =module.exports ={}exports.signup =function(req, res) { res.render('signup');}exports.signin =function(req, res) { res.render('signin ');}exports.dashboard =function(req, res) { res.render('dashboard');}
Agora, execute o aplicativo novamente e tente se inscrever com um endereço de e-mail diferente do que você usou anteriormente. Você será redirecionado adequadamente para o /painel rota.
Mas /dashboard não é uma rota protegida, o que significa que mesmo que um usuário não esteja logado, ele pode vê-la. Não queremos isso, então adicionaremos um /logout route para desconectar o usuário e, em seguida, proteger a rota e testar o que fizemos.
Vamos fazer isso:
Em routes/auth.js adicionamos esta linha:
app.get('/logout',authController.logout);
Em seguida, adicionamos o controlador em app/controllers/authController.js.
export.logout =function(req, res) { req.session.destroy(function(err) { res.redirect('/'); }); }
Agora execute o aplicativo novamente e inscreva-se com um endereço de e-mail diferente.
Depois disso, visite http://localhost:5000/logout para desconectar o usuário. Agora visite http://localhost:5000/dashboard.
Você notará que é bastante acessível. Vamos adicionar um middleware personalizado para proteger essa rota.
Para fazer isso, abrimos app/routes/auth.js e adicione essa função no module.exports bloco, abaixo de todas as outras linhas de código.
função isLoggedIn(req, res, next) { if (req.isAuthenticated()) return next(); res.redirect('/signin');}
Em seguida, modificamos o manipulador de rota do painel para ficar assim:
app.get('/dashboard',isLoggedIn, authController.dashboard);
Agora, quando você executar o aplicativo novamente e tentar visitar a página do painel e não estiver logado, deverá ser redirecionado para a página de login.
Uau! É hora de implementar a parte final:o login.
Primeiro, adicionaremos uma nova estratégia local para login em app/config/passport/passport.js .
//LOCAL SIGNINpassport.use('local-signin', new LocalStrategy( { // por padrão, a estratégia local usa nome de usuário e senha, substituiremos por email usernameField:'email', passwordField:'password', passReqToCallback :true // nos permite repassar toda a requisição para o callback }, function(req, email, password, done) { var User =user; var isValidPassword =function(userpass, password) { return bCrypt.compareSync(password, userpass); } User.findOne({ where:{ email:email } }).then(function(user) { if (!user) { return done(null, false, { message:'Email not exist' }); } if (!isValidPassword(user.password, password)) { return done(null, false, { message:'Senha incorreta.' }); } var userinfo =user. obter(); return done(null, userinfo); }).catch(function(err) { console.log("Error:", err); return done(null, false, { message:'Algo deu errado com seu login' }); }); }));
Nesta estratégia, o
isValidPassword
A função compara a senha inserida com o método de comparação bCrypt, pois armazenamos nossa senha com bcrypt . Se os detalhes estiverem corretos, nosso usuário será conectado.
Agora vá para routes/auth.js e adicione a rota para postagem em / entrar.
app.post('/signin', passaporte.authenticate('local-signin', { successRedirect:'/dashboard', failureRedirect:'/signin' }));
Suas rotas/auth.js devem ficar assim quando você terminar.
var authController =require('../controllers/authcontroller.js');module.exports =function(app, passaporte) { app.get('/signup', authController.signup); app.get('/signin', authController.signin); app.post('/signup', passaporte.authenticate('local-signup', { successRedirect:'/dashboard', failureRedirect:'/signup' } )); app.get('/dashboard', isLoggedIn, authController.dashboard); app.get('/logout', authController.logout); app.post('/signin', passaporte.authenticate('local-signin', { successRedirect:'/dashboard', failureRedirect:'/signin' } )); function isLoggedIn(req, res, next) { if (req.isAuthenticated()) return next(); res.redirect('/signin'); }}
Agora execute o aplicativo e tente fazer login. Você poderá fazer login com qualquer um dos detalhes que usou ao se inscrever e será direcionado para http ://localhost:5000/dashboard/.
Parabéns se você chegou ao final deste tutorial! Usamos com sucesso o Sequelize e o Passport com um banco de dados MySQL.
O código completo para este tutorial pode ser encontrado no GitHub.