рдПрдХ рдореЛрдмрд╛рдЗрд▓ рдРрдк рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛, рдкреНрд░рд╛рдзрд┐рдХрд░рдг, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрдХрдПрдВрдб рд╕реЗрд╡рд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдмреЗрд╢рдХ, рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдк рдмреАрдПрдПрдПрд╕ (рдкрд╛рд░реНрд╕, рдмреИрдХрдПрдВрдбрд▓реЗрд╕, рдЖрджрд┐ ...) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдкрдХрд╛ рдирд┐рд░реНрдгрдп рд╣рдореЗрд╢рд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реЛрддрд╛ рд╣реИред
рдФрд░ рдлрд┐рд░ рднреА рдореИрдВрдиреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдЬреНрдЮрд╛рдд рдХреЗ рд▓рд┐рдП рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬреЛ рдЕрдм рдмрд╣реБрдд рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИрдВ рдФрд░ рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧрд╣рди рдЬреНрдЮрд╛рди рдФрд░ рдЕрдиреБрднрд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рддреЛ рдЪрд▓реЛ рдПрдХ рд╕рд╛рде рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдПрдХ рдЖрдо рдЖрджрдореА рдЕрдкрдиреЗ рдкреНрд░рднрд╛рд╡реА рдФрд░ рд╕рд╣реА рдмреИрдХрдПрдВрдб рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реИред
рдпрд╣ рд▓реЗрдЦ MongoDB рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Express.js рдлреНрд░реЗрдорд╡рд░реНрдХ рдФрд░ Mongoose.js рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ Node.js рдкрд░ рдПрдХ рдореЛрдмрд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП REST API рдХреЗ рдирд┐рд░реНрдорд╛рдг рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдЧрд╛ред рдкрд╣реБрдВрдЪ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо OAuth2orize рдФрд░ Passport.js рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ OAuth 2.0 рддрдХрдиреАрдХ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗрдВрдЧреЗред
рдореИрдВ рдПрдХ рдирд┐рд░рдкреЗрдХреНрд╖ рд╢реБрд░реБрдЖрдд рдХреЗ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рд╕реЗ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВред рдХреЛрдб рдФрд░ рддрд░реНрдХ рдкрд░ рдХрд┐рд╕реА рднреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ рд╕реБрдзрд╛рд░ рдкрд░ рдЦреБрд╢реА!
рд╕рд╛рдордЧреНрд░реА
- Node.js + Express.js, рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡реЗрдм рд╕рд░реНрд╡рд░
- рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдореЗрдВ рддреНрд░реБрдЯрд┐
- рдкреНрд░рддрд┐рд╖реНрдард┐рдд рдПрдкреАрдЖрдИ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ, CRUD
- MongoDB рдФрд░ Mongoose.js
- рдЕрднрд┐рдЧрдо рдирд┐рдпрдВрддреНрд░рдг - OAuth 2.0, Passport.js
рдореИрдВ OSX, IDE -
JetBrains WebStorm рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛
рд╣реВрдВ ред
рдореИрдВрдиреЗ
рдЗрд▓рд┐рдпрд╛ рдХреИрдВрдЯрд░ рдХреЗ рд╕реНрдХреНрд░реИрдирд╛рд╕реНрдЯ рдореЗрдВ Node.js рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рд╕реАрдЦреАрдВ, рдореИрдВ рдЗрд╕рдХреА рдЕрддреНрдпрдзрд┐рдХ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ! (
рдФрд░ рдпрд╣рд╛рдВ рд╣рдм рдкрд░ рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдкреЛрд╕реНрдЯ рд╣реИ )
рдЕрдВрддрд┐рдо рдЪрд░рдг рдореЗрдВ рддреИрдпрд╛рд░ рдкрд░рд┐рдпреЛрдЬрдирд╛
GitHub рдкрд░ рд▓реА рдЬрд╛ рд╕рдХрддреА
рд╣реИ ред рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ npm рдЗрдВрд╕реНрдЯреЙрд▓ рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдВред
1. Node.js + Express.js, рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╡реЗрдм рд╕рд░реНрд╡рд░
Node.js рдореЗрдВ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ I / O рд╣реИ, рдЬреЛ рдПрдХ рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реИ рдЬреЛ рдХрдИ рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдХреНрд╕реЗрд╕ рдХрд░реЗрдЧрд╛ред Express.js рдПрдХ рд╡рд┐рдХрд╕рд┐рдд, рд╣рд▓реНрдХрд╛ рдврд╛рдВрдЪрд╛ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЙрди рд╕рднреА рд░рд╛рд╕реНрддреЛрдВ (рдПрдкреАрдЖрдИ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ) рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗред рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдИ рдЙрдкрдпреЛрдЧреА рдореЙрдбреНрдпреВрд▓ рднреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдПрдХ рдПрдХрд▓ server.js рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдПрдБред рдЪреВрдВрдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ
Express.js рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛, рдЗрд╕реЗ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░реЗрдВред рдерд░реНрдб-рдкрд╛рд░реНрдЯреА рдореЙрдбреНрдпреВрд▓ рдиреЛрдб рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ
npm install modulename
ред
cd NodeAPI npm i express
Express рдиреЛрдб_рдореЙрдбрд▓ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рд╣реИред рдЗрд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ:
var express = require('express'); var app = express(); app.listen(1337, function(){ console.log('Express server listening on port 1337'); });
IDE рдпрд╛ рдХрдВрд╕реЛрд▓ (
node server.js
) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓рд╛рдПрдБред рдпрд╣ рдХреЛрдб рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ: 1337 рдкрд░ рдПрдХ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдмрдирд╛рдПрдЧрд╛ред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдЦреЛрд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рдВрджреЗрд╢
Cannot GET /
ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдЕрднреА рддрдХ рдПрдХ рднреА рдорд╛рд░реНрдЧ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдЕрдЧрд▓рд╛, рдХрдИ рдкрде рдмрдирд╛рдПрдВ рдФрд░ рдореВрд▓ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдмрдирд╛рдПрдВред
var express = require('express'); var path = require('path');
рдЕрдм рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ: 1337 / рдПрдкреА рд╣рдорд╛рд░рд╛ рд╕рдВрджреЗрд╢ рд▓реМрдЯрд╛ рджреЗрдЧрд╛ред localhost: 1337 index.html рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред
рдпрд╣рд╛рдБ рд╣рдо рдПрд░рд░ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдкрд░ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред
2. рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ
рд╡рд┐рдВрд╕реНрдЯрди рд▓реЙрдЧрд┐рдВрдЧ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред рд╣рдо рдЕрдкрдиреЗ рдЖрд╡рд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
npm i winston
рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд░реВрдЯ рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рдлрд┐рд░ рд╡рд╣рд╛рдВ libs / folder рдФрд░ log.js. рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВ
var winston = require('winston'); function getLogger(module) { var path = module.filename.split('/').slice(-2).join('/');
рд╣рдордиреЗ рд▓реЙрдЧ рдХреЗ рд▓рд┐рдП 1 рдкрд░рд┐рд╡рд╣рди рдмрдирд╛рдпрд╛ - рдХрдВрд╕реЛрд▓ рдХреЛред рд╣рдо рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рднреА рд╕реЙрд░реНрдЯ рдФрд░ рд╕рд╣реЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдпрд╛ рдлрд╝рд╛рдЗрд▓ рдореЗрдВред рд▓рдХрдбрд╝рд╣рд╛рд░реЗ рдХреЛ рд╣рдорд╛рд░реЗ server.js рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред
var express = require('express'); var path = require('path');
рд╣рдорд╛рд░рд╛ рдиреНрдпреВрдЬрд╝рд▓реЗрдЯрд░ рдЕрдм рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЕрд▓рдЧ рд╕реЗ рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред 404 рдФрд░ 500 рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдЬреЛрдбрд╝реЗрдВред
app.use(function(req, res, next){ res.status(404); log.debug('Not found URL: %s',req.url); res.send({ error: 'Not found' }); return; }); app.use(function(err, req, res, next){ res.status(err.status || 500); log.error('Internal error(%d): %s',res.statusCode,err.message); res.send({ error: err.message }); return; }); app.get('/ErrorExample', function(req, res, next){ next(new Error('Random error!')); });
рдЕрдм, рдпрджрд┐ рд░рд╛рд╕реНрддреЗ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╣рдорд╛рд░реЗ рд╕рдВрджреЗрд╢ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдЧрд╛ред рдПрдХ рдЖрдВрддрд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░рд╛ рд╣реИрдВрдбрд▓рд░ рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЗрд╕реЗ рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ: 1337 / ErrorExample рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░рдХреЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
3. RESTful API рдПрдВрдбрдкреЙрдЗрдВрдЯ, CRUD
рдХреБрдЫ "рд▓реЗрдЦ" (рд▓реЗрдЦ) рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд░рд╛рд╕реНрддреЗ рдЬреЛрдбрд╝реЗрдВред рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдПрдкреАрдЖрдИ рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рддреЗ рд╣реБрдП рд╣рдм рдкрд░ рдПрдХ рдЕрджреНрднреБрдд
рд▓реЗрдЦ рд╣реИред рдЬрдмрдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ рддрд░реНрдХ рд╕реЗ рдирд╣реАрдВ рднрд░реЗрдВрдЧреЗ, рд╣рдо рдЗрд╕реЗ рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ рдХрд░реЗрдВрдЧреЗ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред
app.get('/api/articles', function(req, res) { res.send('This is not implemented now'); }); app.post('/api/articles', function(req, res) { res.send('This is not implemented now'); }); app.get('/api/articles/:id', function(req, res) { res.send('This is not implemented now'); }); app.put('/api/articles/:id', function (req, res){ res.send('This is not implemented now'); }); app.delete('/api/articles/:id', function (req, res){ res.send('This is not implemented now'); });
рдкреЛрд╕реНрдЯ / рдкреБрдЯ / рдбрд┐рд▓реАрдЯ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ cURL -
httpie рдкрд░ рдПрдХ рдЕрджреНрднреБрдд рдЖрд╡рд░рдг рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢
рдХрд░реВрдВрдЧрд╛ ред рдЖрдЧреЗ рдореИрдВ рдЗрд╕ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред
4. MongoDB рдФрд░ Mongoose.js
рдПрдХ DBMS рдХрд╛ рдЪрдпрди, рдореИрдВ рдлрд┐рд░ рд╕реЗ рдХреБрдЫ рдирдпрд╛ рд╕реАрдЦрдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
MongoDB рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп NoSQL рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-рдЙрдиреНрдореБрдЦ DBMS рд╣реИред
Mongoose.js - рдПрдХ рдЖрд╡рд░рдг рдЬреЛ рдЖрдкрдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдпреЛрдЬрдирд╛рдПрдВ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ рдФрд░
MongoDB рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред
npm i mongoose
рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
npm i mongoose
ред рдореИрдВрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд▓рд┐рдмрд╛рд╕ / рдореЛрдВрдЧреЛрдЬрд╝реЛ.рдЬреЗрдПрд╕ рдлрд╛рдЗрд▓ рдореЗрдВ рдЪреБрдирд╛ рд╣реИред
var mongoose = require('mongoose'); var log = require('./log')(module); mongoose.connect('mongodb://localhost/test1'); var db = mongoose.connection; db.on('error', function (err) { log.error('connection error:', err.message); }); db.once('open', function callback () { log.info("Connected to DB!"); }); var Schema = mongoose.Schema;
рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реНрдХреАрдо рднреА рдШреЛрд╖рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред рд▓реЗрдЦ рдореЗрдВ рдЪрд┐рддреНрд░ рд╡рд╕реНрддреБрдПрдВ рд╣реЛрдВрдЧреАред рдпрд╣рд╛рдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЬрдЯрд┐рд▓ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХрд╛ рднреА рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐
рдЗрд╕рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
nconf рдореЙрдбреНрдпреВрд▓ рдХреЛ
рдЬреЛрдбрд╝рдирд╛ ред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рднреА, рдЙрд╕ рдкреЛрд░реНрдЯ рдХреЛ рд╕рд╣реЗрдЬреЗрдВ рдЬрд┐рд╕ рдкрд░ рд╕рд░реНрд╡рд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореЙрдбреНрдпреВрд▓
npm i nconf
рд╕рд╛рде рд╕реНрдерд╛рдкрд┐рдд рд╣реИред рдЖрд╡рд░рдг рд▓рд┐рдм / config.js рд╣реЛрдЧрд╛
var nconf = require('nconf'); nconf.argv() .env() .file({ file: './config.json' }); module.exports = nconf;
рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдЯ рдореЗрдВ config.json рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред
{ "port" : 1337, "mongoose": { "uri": "mongodb://localhost/test1" } }
Mongoose.js рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди (рдХреЗрд╡рд▓ рд╣реЗрдбрд░ рдореЗрдВ):
var config = require('./config'); mongoose.connect(config.get('mongoose:uri'));
Server.js рдкрд░рд┐рд╡рд░реНрддрди:
var config = require('./libs/config'); app.listen(config.get('port'), function(){ log.info('Express server listening on port ' + config.get('port')); });
рдЕрдм рд╣рдорд╛рд░реЗ рдореМрдЬреВрджрд╛ рд░рд╛рд╕реНрддреЛрдВ рдореЗрдВ CRUD рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЬреЛрдбрд╝реЗрдВред
var log = require('./libs/log')(module); var ArticleModel = require('./libs/mongoose').ArticleModel; app.get('/api/articles', function(req, res) { return ArticleModel.find(function (err, articles) { if (!err) { return res.send(articles); } else { res.statusCode = 500; log.error('Internal error(%d): %s',res.statusCode,err.message); return res.send({ error: 'Server error' }); } }); }); app.post('/api/articles', function(req, res) { var article = new ArticleModel({ title: req.body.title, author: req.body.author, description: req.body.description, images: req.body.images }); article.save(function (err) { if (!err) { log.info("article created"); return res.send({ status: 'OK', article:article }); } else { console.log(err); if(err.name == 'ValidationError') { res.statusCode = 400; res.send({ error: 'Validation error' }); } else { res.statusCode = 500; res.send({ error: 'Server error' }); } log.error('Internal error(%d): %s',res.statusCode,err.message); } }); }); app.get('/api/articles/:id', function(req, res) { return ArticleModel.findById(req.params.id, function (err, article) { if(!article) { res.statusCode = 404; return res.send({ error: 'Not found' }); } if (!err) { return res.send({ status: 'OK', article:article }); } else { res.statusCode = 500; log.error('Internal error(%d): %s',res.statusCode,err.message); return res.send({ error: 'Server error' }); } }); }); app.put('/api/articles/:id', function (req, res){ return ArticleModel.findById(req.params.id, function (err, article) { if(!article) { res.statusCode = 404; return res.send({ error: 'Not found' }); } article.title = req.body.title; article.description = req.body.description; article.author = req.body.author; article.images = req.body.images; return article.save(function (err) { if (!err) { log.info("article updated"); return res.send({ status: 'OK', article:article }); } else { if(err.name == 'ValidationError') { res.statusCode = 400; res.send({ error: 'Validation error' }); } else { res.statusCode = 500; res.send({ error: 'Server error' }); } log.error('Internal error(%d): %s',res.statusCode,err.message); } }); }); }); app.delete('/api/articles/:id', function (req, res){ return ArticleModel.findById(req.params.id, function (err, article) { if(!article) { res.statusCode = 404; return res.send({ error: 'Not found' }); } return article.remove(function (err) { if (!err) { log.info("article removed"); return res.send({ status: 'OK' }); } else { res.statusCode = 500; log.error('Internal error(%d): %s',res.statusCode,err.message); return res.send({ error: 'Server error' }); } }); }); });
рдорд╛рдирдЧреЛ рдФрд░ рд╡рд░реНрдгрд┐рдд рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж - рд╕рднреА рдСрдкрд░реЗрд╢рди рдмреЗрд╣рдж рд╕реНрдкрд╖реНрдЯ рд╣реИрдВред рдЕрдм, рдиреЛрдб.рдЬреЗрдПрд╕ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдкрдХреЛ
mongod
рдХрдорд╛рдВрдб рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
mongo
- рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛, рд╕реЗрд╡рд╛ рд╣реА
mongod
ред рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдХреБрдЫ рднреА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
Httpie рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирдореВрдирд╛ рдЕрдиреБрд░реЛрдз:
http POST http:
рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛
GitHub рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреА
рд╣реИ ред
5. рдЕрднрд┐рдЧрдо рдирд┐рдпрдВрддреНрд░рдг - OAuth 2.0, Passport.js
рдкрд╣реБрдВрдЪ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ OAuth 2 рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реВрдВрдЧрд╛ред рд╢рд╛рдпрдж рдпрд╣ рдмреЗрдорд╛рдиреА рд╣реИ, рд▓реЗрдХрд┐рди рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдиреНрдп OAuth рдкреНрд░рджрд╛рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреА рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЭреЗ Node.js. рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд╛рд╕рд╡рд░реНрдб OAuth2 рдкреНрд░рд╡рд╛рд╣ рдХреЗ рдХрд╛рдо рдХреЗ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рдорд┐рд▓реЗред
Passport.js рд╕реАрдзреЗ рдкрд╣реБрдВрдЪ рдирд┐рдпрдВрддреНрд░рдг рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░реЗрдЧрд╛ред OAuth2 рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╣реА рд▓реЗрдЦрдХ,
oauth2orize рд╕реЗ рдПрдХ рд╕рдорд╛рдзрд╛рди
рдЙрдкрдпреЛрдЧреА рд╣реИ ред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛, рдЯреЛрдХрди MongoDB рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред
рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдЙрди рд╕рднреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рдирдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рдардЧ
- oauth2orize
- рдкрд╛рд╕рдкреЛрд░реНрдЯ
- рдкрд╛рд╕рдкреЛрд░реНрдЯ http
- рдкрд╛рд╕рдкреЛрд░реНрдЯ http-рд╡рд╛рд╣рдХ
- рдкрд╛рд╕рдкреЛрд░реНрдЯ OAuth2-рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд╛рд╕рд╡рд░реНрдб
рдлрд┐рд░, mongoose.js рдореЗрдВ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдЯреЛрдХрди рдХреЗ рд▓рд┐рдП рдпреЛрдЬрдирд╛рдПрдБ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
var crypto = require('crypto');
рд╡рд░реНрдЪреБрдЕрд▓ рдкрд╛рд╕рд╡рд░реНрдб рдкреНрд░реЙрдкрд░реНрдЯреА рдЗрд╕ рдмрд╛рдд рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдореЙрдбрд▓ рдореЗрдВ рдореИрдВрдЧреЛрдЬрд╝ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд▓реЙрдЬрд┐рдХ рдХреЛ рдХреИрд╕реЗ рдПрдореНрдмреЗрдб рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣реИрд╢ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдФрд░ рдирдордХ - рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдирд╣реАрдВ, рд╣рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдПрдВрдЧреЗред
рддреЛ, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕:
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ - рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЬрд┐рд╕рдХрд╛ рдирд╛рдо, рдкрд╛рд╕рд╡рд░реНрдб рд╣реИрд╢ рдФрд░ рдЙрд╕рдХреЗ рдкрд╛рд╕рд╡рд░реНрдб рдХрд╛ рдирдордХ рд╣реИред
- рдХреНрд▓рд╛рдЗрдВрдЯ - рдПрдХ рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬрд┐рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдУрд░ рд╕реЗ рдПрдХреНрд╕реЗрд╕ рджреА рдЬрд╛рддреА рд╣реИред рдЙрдирдХрд╛ рдПрдХ рдирд╛рдо рдФрд░ рдПрдХ рдЧреБрдкреНрдд рдХреЛрдб рд╣реИред
- AccessToken - рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдПрдХ рдЯреЛрдХрди (рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░) рд╕рдордп рдореЗрдВ рд╕реАрдорд┐рдд рд╣реИред
- RefreshToken - рдПрдХ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЯреЛрдХрди, рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдкрд╛рд╕рд╡рд░реНрдб рдкреБрди: рдЕрдиреБрд░реЛрдз рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рдирдП рд╡рд╛рд╣рдХ рдЯреЛрдХрди рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
Config.json рдореЗрдВ, рдЯреЛрдХрди рдЬреАрд╡рдирдХрд╛рд▓ рдЬреЛрдбрд╝реЗрдВ:
{ "port" : 1337, "security": { "tokenLife" : 3600 }, "mongoose": { "uri": "mongodb://localhost/testAPI" } }
рд╣рдо OAuth2 рд╕рд░реНрд╡рд░ рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЕрд▓рдЧ рдХрд░рддреЗ рд╣реИрдВред Oauth.js рдиреЗ рдкрд╛рд╕рдкреЛрд░реНрдЯ.js рдХреА "рд░рдгрдиреАрддрд┐рдпреЛрдВ" рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рд╣реИ, рд╣рдо рдЙрдирдореЗрдВ рд╕реЗ 3 рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ - 2 рдХреЛ OAuth2 рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо-рдкрд╛рд╕рд╡рд░реНрдб рдкреНрд░рд╡рд╛рд╣, 1 рдЯреЛрдХрди рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
var config = require('./config'); var passport = require('passport'); var BasicStrategy = require('passport-http').BasicStrategy; var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy; var BearerStrategy = require('passport-http-bearer').Strategy; var UserModel = require('./mongoose').UserModel; var ClientModel = require('./mongoose').ClientModel; var AccessTokenModel = require('./mongoose').AccessTokenModel; var RefreshTokenModel = require('./mongoose').RefreshTokenModel; passport.use(new BasicStrategy( function(username, password, done) { ClientModel.findOne({ clientId: username }, function(err, client) { if (err) { return done(err); } if (!client) { return done(null, false); } if (client.clientSecret != password) { return done(null, false); } return done(null, client); }); } )); passport.use(new ClientPasswordStrategy( function(clientId, clientSecret, done) { ClientModel.findOne({ clientId: clientId }, function(err, client) { if (err) { return done(err); } if (!client) { return done(null, false); } if (client.clientSecret != clientSecret) { return done(null, false); } return done(null, client); }); } )); passport.use(new BearerStrategy( function(accessToken, done) { AccessTokenModel.findOne({ token: accessToken }, function(err, token) { if (err) { return done(err); } if (!token) { return done(null, false); } if( Math.round((Date.now()-token.created)/1000) > config.get('security:tokenLife') ) { AccessTokenModel.remove({ token: accessToken }, function (err) { if (err) return done(err); }); return done(null, false, { message: 'Token expired' }); } UserModel.findById(token.userId, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Unknown user' }); } var info = { scope: '*' } done(null, user, info); }); }); } ));
рдЯреЛрдХрди рдЬрд╛рд░реА рдХрд░рдиреЗ рдФрд░ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Oauth2.js рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдПрдХ рдПрдХреНрд╕рдЪреЗрдВрдЬ рд░рдгрдиреАрддрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо-рдкрд╛рд╕рд╡рд░реНрдб рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЯреЛрдХрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ, рдПрдХ рдЕрдиреНрдп рддрд╛рдЬрд╝рд╛_рдЯреЛрдХрди рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИред
var oauth2orize = require('oauth2orize'); var passport = require('passport'); var crypto = require('crypto'); var config = require('./config'); var UserModel = require('./mongoose').UserModel; var ClientModel = require('./mongoose').ClientModel; var AccessTokenModel = require('./mongoose').AccessTokenModel; var RefreshTokenModel = require('./mongoose').RefreshTokenModel;
рдЗрди рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, server.js рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
var oauth2 = require('./libs/oauth2'); app.use(passport.initialize()); require('./libs/auth'); app.post('/oauth/token', oauth2.token); app.get('/api/userInfo', passport.authenticate('bearer', { session: false }), function(req, res) {
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реБрд░рдХреНрд╖рд╛ рд╕реНрдерд╛рдиреАрдп рд╣реЛрд╕реНрдЯ рдкрддреЗ рдкрд░ рд╣реИ: 1337 / рдПрдкреАрдЖрдИ / userInfoред
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рддрдВрддреНрд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВ Node.js рдкрд░ рдПрдХ рдЖрд╡реЗрджрди рджреВрдВрдЧрд╛, рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдЧрд╛ рдФрд░ рд╕рдВрдЧреНрд░рд╣ рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХреЛ рд╣рдЯрд╛ рджреЗрдЧрд╛ред рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рдЯреЛрдХрди рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рд╕рд╛рдл рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд▓реЙрдиреНрдЪ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ :)
var log = require('./libs/log')(module); var mongoose = require('./libs/mongoose').mongoose; var UserModel = require('./libs/mongoose').UserModel; var ClientModel = require('./libs/mongoose').ClientModel; var AccessTokenModel = require('./libs/mongoose').AccessTokenModel; var RefreshTokenModel = require('./libs/mongoose').RefreshTokenModel; var faker = require('Faker'); UserModel.remove({}, function(err) { var user = new UserModel({ username: "andrey", password: "simplepassword" }); user.save(function(err, user) { if(err) return log.error(err); else log.info("New user - %s:%s",user.username,user.password); }); for(i=0; i<4; i++) { var user = new UserModel({ username: faker.random.first_name().toLowerCase(), password: faker.Lorem.words(1)[0] }); user.save(function(err, user) { if(err) return log.error(err); else log.info("New user - %s:%s",user.username,user.password); }); } }); ClientModel.remove({}, function(err) { var client = new ClientModel({ name: "OurService iOS client v1", clientId: "mobileV1", clientSecret:"abc123456" }); client.save(function(err, client) { if(err) return log.error(err); else log.info("New client - %s:%s",client.clientId,client.clientSecret); }); }); AccessTokenModel.remove({}, function (err) { if (err) return log.error(err); }); RefreshTokenModel.remove({}, function (err) { if (err) return log.error(err); }); setTimeout(function() { mongoose.disconnect(); }, 3000);
рдпрджрд┐ рдЖрдкрдиреЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рдмрдирд╛рдпрд╛ рд╣реИ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдЖрджреЗрд╢ рдЖрдкрдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдВрдЧреЗред рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рдореИрдВ
httpie рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛
рд╣реВрдВ ред
http POST http://localhost:1337/oauth/token grant_type=password client_id=mobileV1 client_secret=abc123456 username=andrey password=simplepassword http POST http://localhost:1337/oauth/token grant_type=refresh_token client_id=mobileV1 client_secret=abc123456 refresh_token=TOKEN http http://localhost:1337/api/userinfo Authorization:'Bearer TOKEN'
рдЪреЗрддрд╛рд╡рдиреА! рдЙрддреНрдкрд╛рджрди рд╕рд░реНрд╡рд░ рдкрд░ HTTPS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ, рдпрд╣ OAuth 2 рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рджреНрд╡рд╛рд░рд╛ рдирд┐рд╣рд┐рдд рд╣реИред рдФрд░ рд╕рд╣реА рдкрд╛рд╕рд╡рд░реНрдб рд╣реИрд╢рд┐рдВрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛ред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде https рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдХрдИ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред
рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐
GitHub рдХреЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рднреА рдХреЛрдб рдирд┐рд╣рд┐рдд рд╣реИрдВред
рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ
mongod
npm install
рдЪрд▓рд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ,
mongod
,
node dataGen.js
(рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ), рдФрд░ рдлрд┐рд░
node server.js
ред
рдпрджрд┐ рд▓реЗрдЦ рдХреЗ рдХрд┐рд╕реА рднреА рднрд╛рдЧ рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдХреГрдкрдпрд╛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЗрд╕реЗ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВред рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╕рдореАрдХреНрд╖рд╛рдПрдБ рдЙрдкрд▓рдмреНрдз рд╣реЛрдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдореИрдВ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдиреЛрдб.рдЬреЗрдПрд╕ рдПрдХ рдЕрдЪреНрдЫрд╛, рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╕рд░реНрд╡рд░ рд╕рдорд╛рдзрд╛рди рд╣реИред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-рдЙрдиреНрдореБрдЦ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде MongoDB рдПрдХ рдмрд╣реБрдд рд╣реА рдЕрд╕рд╛рдорд╛рдиреНрдп, рд▓реЗрдХрд┐рди рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рдЙрдкрдпреЛрдЧреА рдЙрдкрдХрд░рдг рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред Node.js рдХреЗ рдЖрд╕рдкрд╛рд╕ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╕рдореБрджрд╛рдп рд╣реИ, рдЬрд╣рд╛рдВ рдХрдИ рдУрдкрди-рд╕реЛрд░реНрд╕ рд╡рд┐рдХрд╛рд╕ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, oauth2orize рдФрд░ рдкрд╛рд╕рдкреЛрд░реНрдЯ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛, рдЬреЗрд░реЗрдб рд╣реИрдиреНрд╕рди рдиреЗ рдЕрджреНрднреБрдд рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдХреА рд╣реИрдВ рдЬреЛ рдХрд┐ рдареАрдХ рд╕реЗ рд╕рдВрд░рдХреНрд╖рд┐рдд рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рдЖрд╕рд╛рди рдмрдирд╛рддреЗ рд╣реИрдВред