ããããBudget ManagerãšåŒã°ããæ¬æ ŒçãªWebã¢ããªã±ãŒã·ã§ã³ã®éçºã«åããããã·ãªãŒãºã®æåã®è³æã§ãã äœæ¥äžã«äœ¿çšãããäž»ãªãœãããŠã§ã¢ããŒã«ã¯ããµãŒããŒçšã®Node.jsãããã³ããšã³ãçšã®Vue.jsãããŒã¿ããŒã¹ãšããŠã®MongoDBã§ãã

ãããã®è³æã¯ãJavaScriptã«ç²ŸéããŠãããNode.jsãnpmãããã³MongoDBã®åºæ¬ãçè§£ããŠãããNode-Vue-MongoDBãã³ãã«ããã³é¢é£æè¡ãåŠã³ããèªè
ã察象ãšããŠããŸãã ã¢ããªã±ãŒã·ã§ã³ããŒãããäœæããã®ã§ããæ°ã«å
¥ãã®ã³ãŒããšãã£ã¿ãŒãçšæããŠãã ããã ãããžã§ã¯ããè€éã«ããªãããã«ãç§ãã¡ã¯Vuexã䜿çšãããäºæ¬¡çãªããšã«æ°ãåãããããšãªããæãéèŠãªããšã«éäžããããšããŸãã
ãã®è³æã®èè
ã§ãããã©ãžã«ã®éçºè
ã¯ã圌ã¯JavaScriptã®ç¬¬äžäººè
ãšã¯ã»ã©é ãããæ°ããç¥èãæ±ããŠã圌ãèŠã€ãããã®ãä»ã®äººãšå
±æããæºåãã§ããŠãããšèšããŸãã
ããã§ã¯ã次ã®åé¡ãæ€èšããŸãã
- ãããžã§ã¯ãæ§é ã®ç·šæã
 
- 䜿çšãããã©ã€ãã©ãªã®äŸåé¢ä¿ã®ã€ã³ã¹ããŒã«ãšèª¬æã
 
- MongoDBã§ã®äœæ¥ãšMongooseã¢ãã«ã®äœæã
 
- ã¢ããªã±ãŒã·ã§ã³APIã¡ãœããã®éçºã
 
- ãšã¯ã¹ãã¬ã¹ã«ãŒãã®æºåã
 
- Passport.jsã䜿çšããJWTèªèšŒã®æ§æã
 
- Postmanã䜿çšããŠãããžã§ã¯ãããã¹ãããŸãã
 
ç§ãã¡ãåãçµãã§
ãããããžã§ã¯ãã®ã³ãŒãã¯ã GitHubã«ãããŸãã
ãããžã§ã¯ãæ§é ãšäŸåé¢ä¿ã®ã€ã³ã¹ããŒã«
ãŸãããããžã§ã¯ãã®ãã©ã«ããŒæ§é ãäœæããŸããããã¯ãäœæ¥ã®æåã®æ®µéã§æ¬¡ã®ããã«ãªããŸãã
 APIãã©ã«ããŒæ§é
APIãã©ã«ããŒæ§é ãããªã¢ã«ãé²ããã«ã€ããŠããã®æ§é ã倧å¹
ã«æ¡åŒµããŸãã
次ã«ãããã€ãã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ããããžã§ã¯ãã®ã«ãŒããã©ã«ããŒïŒããã§ã¯
focus-budget-manager ïŒã«ç§»åãã 
npm initã³ãã³ãã§ä»¥åã«
package.jsonããŠã次ã®ã³ãã³ããå®è¡ããŸãã
 npm i --save express body-parser mongoose consign cors bcrypt jsonwebtoken morgan passport passport-jwt module-alias 
ãããã®äŸåé¢ä¿ãšãããžã§ã¯ãã§ã®åœ¹å²ã®äžéšãæ€èšããŠãã ããã
- ãšã¯ã¹ãã¬ã¹ ããã¯Node.jsã®ãã¬ãŒã ã¯ãŒã¯ã§ãããAPIã®éçºã容æã«ããããã«äœ¿çšããŸãã
 
- ããã£ããŒãµãŒã ãã®ããã±ãŒãžã¯ãNode.jsã®ã¯ãšãªæ¬æããŒãµãŒã§ãã åä¿¡ãªã¯ãšã¹ãã®æ¬æããã³ãã©ãŒã«æž¡ãåã«è§£æããã®ã«åœ¹ç«ã¡ãŸãããã®çµæã req.bodyããããã£ã䜿çšããŠããããåŠçã§ããŸãã
 
- ãã³ã°ãŒã¹ã ããã¯ãéåæç°å¢ã§åäœããããã«èšèšãããMongoDBã®ãªããžã§ã¯ãã¢ããªã³ã°ããŒã«ã§ãã
 
- å§èšã ãã®ããã±ãŒãžã¯è£å©ã§ããã䜿çšããå¿
èŠã¯ãããŸããã èµ·åã¹ã¯ãªãããæŽçããããã«èšèšãããŠããŸãã
 
- CORSã ãã®ããã±ãŒãžã¯ãCORSãã¢ã¯ãã£ãã«ããããã«äœ¿çšã§ããConnect / Expressãã«ããŒããŒã«ã§ãã
 
- Bcryptã ãã®ããã±ãŒãžã䜿çšããŠãæå·åã®ãå¡©ããšããã·ã¥ãçæããŸãã
 
- ã¢ãŒã¬ã³ ããã¯ãHTTPèŠæ±ãèšé²ããããã«èšèšãããNode.jsã®ãã«ããŒã§ãã
 
- ã¢ãžã¥ãŒã«ã®ãšã€ãªã¢ã¹ã ãã®ããã±ãŒãžã䜿çšãããšããã©ã«ããŒã®ãšã€ãªã¢ã¹ãäœæããNode.jsã«ç¬èªã®ã¢ãžã¥ãŒã«ãã¹ãç»é²ã§ããŸãã
 
ããã±ãŒãžãã€ã³ã¹ããŒã«ããåŸãGitã䜿çšããäºå®ãããå Žåã¯ããããžã§ã¯ãã®ã«ãŒããã©ã«ããŒã«
.gitignoreãã¡ã€ã«ãäœæããŸãã 以äžãèšè¿°ããŸãïŒ
 /node_modules/ 
æºåäœæ¥ãå®äºããã®ã§ãããã°ã©ãã³ã°ãå§ããŸãã
ãã¡ã€ã«BudgetManagerAPI / config / index.js
BudgetManagerAPI/config index.js BudgetManagerAPI/configãã¡ã€ã«ãäœæããæ¬¡ã®ã³ãŒãã远å ããŸãã
 module.exports = { secret: 'budgetsecret', session: { session: false }, database: 'mongodb://127.0.0.1:27017/budgetmanager' } 
ãã®ãã¡ã€ã«ã«ã¯ãããŒã¿ããŒã¹æ¥ç¶ãã©ã¡ãŒã¿ãŒãšãJWTããŒã¯ã³ã®äœæã«äœ¿çšããç§å¯éµãå«ãŸããŠããŸãã
ããã¯ãããŒã«ã«MongoDBãµãŒããŒã§åäœããããšã«ãªã£ãŠããŸãã åæã«ãè¡
127.0.0.1:27017 localhostã䜿çšã§ããŸãã å¿
èŠã«å¿ããŠãããšãã°MLabsã䜿çšããŠäœæãããMongoDBã¯ã©ãŠãããŒã¿ããŒã¹ãæäœã§ããŸãã
ãã¡ã€ã«BudgetManagerAPI / app / models / user.js
JWTèªèšŒã«äœ¿çšããã
Userã¢ãã«ãäœæã
User ã ãããè¡ãã«ã¯ã 
BudgetManagerAPI/appãã©ã«ããŒã«ç§»åãããã®äžã«
modelsãã£ã¬ã¯ããªãŒãäœæãããã®äžã«
user.jsãã¡ã€ã«ã
user.jsãŸãã ãã¡ã€ã«ã®å
é ã§ãäŸåé¢ä¿ãæ¥ç¶ããŸãã
 const mongoose = require('mongoose'),     bcrypt = require('bcrypt'); 
ããã§ã¯ã 
Userã¢ãã«ãäœæããããã«
mongooseããã±ãŒãžãå¿
èŠã§ã
bcryptããã±ãŒãžããŒã«ã¯ããŠãŒã¶ãŒãã¹ã¯ãŒããããã·ã¥ããããã«äœ¿çšãããŸãã
ãã®åŸãåããã¡ã€ã«ã«æ¬¡ã远å ããŸãã
 const Schema = mongoose.Schema({ username: {   type: String,   unique: true,   required: true }, password: {   type: String,   required: true }, clients: [{}] }); 
ãã®ã³ãŒãã¯ã 
UserããŒã¿ã¹ããŒããäœæããããã®ãã®ã§ãã ãã®èª¬æã«ãããæ¬¡ã®ããŒã¿ãã·ã¹ãã ã®ãŠãŒã¶ãŒã«å²ãåœãŠãããŸãã
- ãŠãŒã¶ãŒå
 
- ãã¹ã¯ãŒã
 
- ã¯ã©ã€ã¢ã³ãã®ãªã¹ãïŒ clientsïŒã
 
ã¯ã©ã€ã¢ã³ãæ
å ±ã«ã¯ãé»åã¡ãŒã«ã¢ãã¬ã¹ïŒé»åã¡ãŒã«ïŒãååïŒååïŒãé»è©±ïŒé»è©±ïŒãããã³è²¡åæžé¡ïŒäºç®ïŒãå«ãŸããŸãã 財åããã¥ã¡ã³ãã«ã¯ãç¶æ
ãã¿ã€ãã«ãã¢ã€ãã ã䟡栌ãªã©ã®ããŒã¿ãå«ãŸããŸãã
user.jsãã¡ã€ã«ãåŒãç¶ã䜿çšããæ¬¡ã®ã³ãŒãã远å ããŸãã
 //       -       Schema.pre('save', function (next) { const user = this; if (this.isModified('password') || this.isNew) {   bcrypt.genSalt(10, (error, salt) => {   if (error) return next(error);   bcrypt.hash(user.password, salt, (error, hash) => {     if (error) return next(error);     user.password = hash;       next();     });   }); } else {   return next(); } }); 
ãã®é¢æ°ã§ã¯ããŠãŒã¶ãŒãã¹ã¯ãŒãã®æå·åãœã«ããšããã·ã¥ãçæããŸãã
ãã®é¢æ°ã®ã³ãŒãã«åŸã£ãŠããã¹ã¯ãŒããæ¯èŒããã·ã¹ãã ãžã®ãŠãŒã¶ãŒã¢ã¯ã»ã¹ã®æå¹æ§ã確èªãã颿°ã远å ããŸãã
 Schema.methods.comparePassword = function (password, callback) { bcrypt.compare(password, this.password, (error, matches) => {   if (error) return callback(error);   callback(null, matches); }); }; 
次ã«ããã¡ã€ã«ã®æåŸã§ã 
Userã¢ãã«ãäœæã
User ã
 mongoose.model('User', Schema); 
ãã¡ã€ã«BudgetManagerAPI / config / passport.js
Userã¢ãã«ã®æºåãã§ãããã 
passport.jsãã¡ã€ã«ã
BudgetManagerAPI/configãã©ã«ããŒã«äœæããŸãã äŸåé¢ä¿æ¥ç¶ã䜿çšããŠãã®ãã¡ã€ã«ã®äœæ¥ãå§ããŸãããã
 const PassportJWT = require('passport-jwt'),     ExtractJWT = PassportJWT.ExtractJwt,     Strategy = PassportJWT.Strategy,     config = require('./index.js'),     models = require('@BudgetManager/app/setup'); 
Userã¢ãã«ã
passport-jwtã¯
passport-jwtããã±ãŒãžãå¿
èŠã§ã
passport-jwtã¯èªèšŒãæŽçããããã®ãã®ã§ãã
次ã«ããã®ãã¡ã€ã«ã«æ¬¡ã远å ããŸãã
 module.exports = (passport) => { const User = models.User; const parameters = {   secretOrKey: config.secret,   jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken() }; passport.use(new Strategy(parameters, (payload, done) => {   User.findOne({ id: payload.id }, (error, user) => {     if (error) return done(error, false);     if (user) done(null, user);     else done(null, false);   }); })); } 
ããã§ã¯ã 
Userã¢ãã«ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã¯ã©ã€ã¢ã³ãããåä¿¡ããJWTããŒã¯ã³ãæ€çŽ¢ããŠãŠãŒã¶ãŒãèŠã€ããŸãã
ãã¡ã€ã«BudgetManagerAPI / config / database.js
BudgetManagerAPI/configãã©ã«ããŒã§ã 
database.jsæäœãæ
åœãã
database.jsãã¡ã€ã«ãäœæããŸãã ãã®ãã¡ã€ã«ã«æ¬¡ã远å ããŸãã
 module.exports = (mongoose, config) => { const database = mongoose.connection; mongoose.Promise = Promise; mongoose.connect(config.database, {   useMongoClient: true,   promiseLibrary: global.Promise }); database.on('error', error => console.log(`Connection to BudgetManager database failed: ${error}`)); database.on('connected', () => console.log('Connected to BudgetManager database')); database.on('disconnected', () => console.log('Disconnected from BudgetManager database')); process.on('SIGINT', () => {   database.close(() => {     console.log('BudgetManager terminated, connection closed');     process.exit(0);   }) }); }; 
ããã§ã¯ãæåã«
mongooseãæšæºã®
Promiseãªããžã§ã¯ãã®äœ¿çšã«åãæ¿ããŸããã ãããè¡ããªããšãã³ã³ãœãŒã«ã«èŠåã衚瀺ãããå ŽåããããŸãã æ¬¡ã«ãæšæºã®
mongooseæ¥ç¶ãäœæããŸããã
ãµãŒããŒã®ã»ããã¢ããããµãŒãã¹/ index.jsãã¡ã€ã«
ããã€ãã®è£å©ãµãã·ã¹ãã ãåŠçããåŸããµãŒããŒã®æ§æãéå§ããŸãã 
servicesãã©ã«ããŒã«ç§»åããæ¢ã«ãã®äžã«ãã
index.jsãã¡ã€ã«ãéããŸãã 以äžã远å ããŸãã
 require('module-alias/register'); const http = require('http'),     BudgetManagerAPI = require('@BudgetManagerAPI'),     BudgetManagerServer = http.Server(BudgetManagerAPI),     BudgetManagerPORT = process.env.PORT || 3001,     LOCAL = '0.0.0.0'; BudgetManagerServer.listen(BudgetManagerPORT, LOCAL, () => console.log(`BudgetManagerAPI running on ${BudgetManagerPORT}`)); 
åŸã§èšå®ãã
module_aliasãæ¥ç¶ããããšããå§ããŸãïŒãã®æé ã¯ãªãã·ã§ã³ã§ããããã®ã¢ãããŒãã¯ã³ãŒãããããããã«ããã®ã«åœ¹ç«ã¡ãŸãïŒã 
module_alias代ããã«
@BudgetManagerAPIããã±ãŒãžã䜿çšããªãå Žåã¯ã. 
module_alias / 
@BudgetManagerAPI / 
@BudgetManagerAPIãèšè¿°ããå¿
èŠããã
./services/BudgetManagerAPI/config ã
ãµãŒããŒãèµ·åããã«ã¯ããããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã«ç§»åãã䜿çšããã³ãã³ãã©ã€ã³ã€ã³ã¿ãŒããªã¿ãŒã«
node servicesã³ãã³ããå
¥åã
node services ã
ãã¡ã€ã«BudgetManagerAPI / config / app.js
BudgetManagerAPI/configãã£ã¬ã¯ããªã§ã 
app.jsãã¡ã€ã«ãäœæããŸãã éå§ããã«ã¯ãäŸåé¢ä¿ãæ¥ç¶ããŸãããã
 const express = require('express'),     app = express(),     bodyParser = require('body-parser'),     mongoose = require('mongoose'),     morgan = require('morgan'),     consign = require('consign'),     cors = require('cors'),     passport = require('passport'),     passportConfig = require('./passport')(passport),     jwt = require('jsonwebtoken'),     config = require('./index.js'),     database = require('./database')(mongoose, config); 
passportConfig = require('./passport')(passport)ã¯ã 
passportã®æ§æãã¡ã€ã«ãã€ã³ããŒããã 
passport.jsã«ã¯æ¬¡ã®ã³ãã³ãããããããåŒæ°ãšããŠ
passportãæž¡ããŸãã

ãã®ã¢ãããŒãã®ãããã§ã 
passport.jsãã¡ã€ã«å
ã®
passport.jsãæ¥ç¶ããããšãªãæäœã§ããŸãã
次ã«ã 
app.jsãã¡ã€ã«ã§ãããã±ãŒãžã®æäœãéå§ããç§å¯ããŒãèšå®ããŸãã
 app.use(express.static('.')); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(morgan('dev')); app.use(cors()); app.use(passport.initialize()); app.set('budgetsecret', config.secret); 
ãŸãã¯ã 
corsããã±ãŒãžã䜿çšãã代ããã«ã次ã®ããšãå®è¡ã§ããŸãã
 app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); 
package.jsonã®æ§æ
ãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã«ç§»åãã 
package.jsonãéããŠã 
dependenciesãããã¯ã®çŽåã«ä»¥äžã远å ããŸãã
 "homepage": "https://github.com/gdomaradzki/focus-gestor-orcamentos#readme", "_moduleAliases": {   "@root": ".",   "@BudgetManager": "./services/BudgetManagerAPI",   "@BudgetManagerModels":"./services/BudgetManagerAPI/app/models",   "@BudgetManagerAPI":"./services/BudgetManagerAPI/config/app.js",   "@config": "./services/BudgetManagerAPI/config/index.js" }, "dependencies": { 
dependenciesãããã¯ã¯æ¢ã«ãã¡ã€ã«å
ã«ããããã 
_moduleAliases homepageãš
_moduleAliasesãããã¯ã远å ããã ãã§ããããšã«æ³šæããŠãã ããã
ãããã®å€æŽã«ããã 
@rootãšã€ãªã¢ã¹ã䜿çšããŠãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã«ã¢ã¯ã»ã¹ãã 
@rootãšã€ãªã¢ã¹ã䜿çšããŠ
index.jsæ§æãã¡ã€ã«ã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã
ãã¡ã€ã«BudgetManagerAPI / app / setup / index.js
ãšã€ãªã¢ã¹ãèšå®ã
BudgetManagerAPI/app ã 
BudgetManagerAPI/appãã©ã«ããŒã«ç§»åããŠãæ°ãã
setupãã©ã«ããŒãäœæãããã®äžã«
index.jsãã¡ã€ã«ãäœæããŸãã 以äžã远å ããŸãã
 const mongoose = require('mongoose'),    UserModel = require('@BudgetManagerModels/user');; const models = { User: mongoose.model('User') } module.exports = models; 
ä»ã®äœããã¢ããªã±ãŒã·ã§ã³ã«ããŒããããåã«ã¢ãã«ã®ããŒãã確å®ã«ããããã«ãããè¡ããŸãã
ãã¡ã€ã«BudgetManagerAPI / app / api / auth.js
çŸåšãAPIã¡ãœããã®ããã€ããäœæãå§ããŠããŸãã 
BudgetManagerAPI/appãã©ã«ããŒã«ç§»åããŠããã®äžã«
apiãã£ã¬ã¯ããªãŒãäœæãããã®äžã«
auth.jsãã¡ã€ã«ã
auth.jsãŸãã ç§ãã¡ã¯ããã«ä»¥äžãæžããŸãïŒ
 const mongoose = require('mongoose'),     jwt = require('jsonwebtoken'),     config = require('@config'); 
module_aliasã¢ãžã¥ãŒã«ã®ãããã§ãã³ãŒãã¯ãªãŒããŒãäœæããããšã«æ³šæããŠãã ããã ããã§ãªããã°ãç§ã¯æ¬¡ã®ãããªãã®ãæžããªããã°ãªããŸããïŒ
 config = require('./../../config); 
ããã§ãããã±ãŒãžãæ¥ç¶ããåŸãåããã¡ã€ã«ã§æ¬¡ã®ããšãè¡ããŸãã
 const api = {}; api.login = (User) => (req, res) => { User.findOne({ username: req.body.username }, (error, user) => {   if (error) throw error;   if (!user) res.status(401).send({ success: false, message: 'Authentication failed. User not found.' });   else {     user.comparePassword(req.body.password, (error, matches) => {       if (matches && !error) {         const token = jwt.sign({ user }, config.secret);         res.json({ success: true, message: 'Token granted', token });       } else {         res.status(401).send({ success: false, message: 'Authentication failed. Wrong password.' });       }     });   } }); } 
ããã§ã¯ãå¿
èŠãªãã¹ãŠã®ã¡ãœãããä¿åãã空ã®
apiãªããžã§ã¯ããäœæããŸãã æåã«ã 
Userã¡ãœããã
loginã¡ãœããã«æž¡ããŸããããã§ã¯ã 
Userã¢ãã«ã«ã¢ã¯ã»ã¹ããã¡ãœãããå¿
èŠãªã®ã§ã次ã«ã 
reqããã³
resåŒæ°ãæž¡ããŸãã
ãã®ã¡ãœããã¯ã 
User usernameäžèŽãã
Userãªããžã§ã¯ããæ€çŽ¢ã
username ã ãŠãŒã¶ãŒåãèªèã§ããªãå Žåã¯ãšã©ãŒãçºçããããã§ãªãå Žåã¯ãŠãŒã¶ãŒã«é¢é£ä»ããããŠãããã¹ã¯ãŒããšããŒã¯ã³ã確èªããŸãã
次ã«ãããŒã¯ã³ãåä¿¡ããŠââè§£æãããã1ã€ã®
apiã¡ãœãããå¿
èŠã§ãã
 api.verify = (headers) => { if (headers && headers.authorization) {   const split = headers.authorization.split(' '); if (split.length === 2) return split[1];   else return null; } else return null; } 
ãã®ã¡ãœããã¯ããããŒããã§ãã¯ãã 
AuthorizationããããŒãååŸããŸãã ããããã¹ãŠã®ã¹ãããã®åŸãæçµçã«
apiãªããžã§ã¯ãããšã¯ã¹ããŒãã§ããŸãã
 module.exports = api; 
API RoutesãBudgetManagerAPI / app / routes / auth.jsãã¡ã€ã«
APIã«ãŒããäœæããŸãããã ãããè¡ãã«ã¯ã 
services/BudgetManagerAPI/appãã©ã«ããŒã«ç§»åãããã®äžã«
routesãã£ã¬ã¯ããªãäœæããŸããããã§ã次ã®å
容ã®
auth.jsãã¡ã€ã«ãäœæããŸãã
 const models = require('@BudgetManager/app/setup'); module.exports = (app) => { const api = app.BudgetManagerAPI.app.api.auth; app.route('/')    .get((req, res) => res.send('Budget Manager API')); app.route('/api/v1/auth')    .post(api.login(models.User)); } 
ãã®ã¢ãžã¥ãŒã«ã«
appãªããžã§ã¯ããæž¡ãã®ã§ãã«ãŒããèšå®ã§ããŸãã ããã§ã 
api宿°ãèšå®ããŸããããã¯ã 
apiãã©ã«ããŒå
ã®
auth.jsãã¡ã€ã«ãæäœããããã«äœ¿çšããŸãã ããã§ã¯ãããã©ã«ãã«ãŒã
'/'ãèšå®ããŸããã¢ã¯ã»ã¹ãããšãæååãBudget Manager APIãããŠãŒã¶ãŒã«æž¡ãããŸãã æ¬¡ã«ãã«ãŒã
'/api/v1/auth'ãäœæããŸãïŒPOSTèŠæ±ã䜿çšãããäœæ¥çšïŒã ãã®ã«ãŒããæäŸããã«ã¯ã 
loginã¡ãœããã䜿çšããŠã 
Userã¢ãã«ãåŒæ°ãšããŠæž¡ããŸãã
ãã¡ã€ã«BudgetManagerAPI / config / app.js
次ã«ã 
BudgetManagerAPI/configãã©ã«ããŒã«ãã
app.jsãã¡ã€ã«ã«æ»ããæ¬¡ã®è¡ã远å ããŸãïŒ 
app.set('budgetsecret', config.secret)ã¬ã€ãã©ã€ã³ãšããŠæå®ãããŠããŸãã2åç®ã«ãã¡ã€ã«ã«è¿œå ããå¿
èŠã¯ãããŸããïŒã
 app.set('budgetsecret', config.secret); consign({ cwd: 'services' })     .include('BudgetManagerAPI/app/setup')     .then('BudgetManagerAPI/app/api')     .then('BudgetManagerAPI/app/routes')     .into(app); module.exports = app; 
ããã§ã¯ãä»ã®ã¢ã¯ã·ã§ã³ãå®è¡ããåã«ã 
setupãã©ã«ããŒã®ã³ã³ãã³ããèªã¿èŸŒãŸããŠãããã©ããã確èªããã¢ãã«ãæåã«ã€ã³ã¹ã¿ã³ã¹åãããããã«ããŸãã æ¬¡ã«ãAPIã¡ãœãããããŒãããæåŸã«ã«ãŒããããŒãããŸãã
ãã¡ã€ã«BudgetManagerAPI / app / api / user.js
BudgetManagerAPI/app/apiãã©ã«ããŒã«
user.js ããã®äžã«
user.jsãã¡ã€ã«ãäœæããŸãã æ¬¡ã®ã³ãŒããå
¥ããŠãã ããïŒ
 const mongoose = require('mongoose'); const api = {}; api.setup = (User) => (req, res) => { const admin = new User({   username: 'admin',   password: 'admin',   clients: [] }); admin.save(error => {   if (error) throw error; console.log('Admin account was succesfully set up');   res.json({ success: true }); }) } 
setupæ¹æ³ã§ã¯ããããã°çšã®ç®¡çè
ã¢ã«ãŠã³ããäœæã§ããŸãã 宿ããã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®ã¢ã«ãŠã³ãã¯ããã§ã¯ãããŸããã
次ã«ãåããã¡ã€ã«å
ã§ããã¹ãç®çã§äœ¿çšããã¡ãœãããäœæããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ã«ç»é²ããèªèšŒã¡ã«ããºã ã確èªããå¿
èŠããããã¹ãŠã®ãŠãŒã¶ãŒããªã¹ãã§ããŸãã
 api.index = (User, BudgetToken) => (req, res) => { const token = BudgetToken; if (token) {   User.find({}, (error, users) => {     if (error) throw error;     res.status(200).json(users);   }); } else return res.status(403).send({ success: false, message: 'Unauthorized' }); } 
次ã«ãåŸã§å¿
èŠã«ãªã
signupã¡ãœãããäœæããŸãã æ°ãããŠãŒã¶ãŒãç»é²ããããã«èšèšãããŠããŸãã
 api.signup = (User) => (req, res) => { if (!req.body.username || !req.body.password) res.json({ success: false, message: 'Please, pass a username and password.' }); else {   const newUser = new User({     username: req.body.username,     password: req.body.password,     clients: []   });   newUser.save((error) => {     if (error) return res.status(400).json({ success: false, message:  'Username already exists.' });     res.json({ success: true, message: 'Account created successfully' });   }) } } module.exports = api; 
ããã§ãæ°ãããŠãŒã¶ãŒãç»é²ããããšãããšãã«ã 
usernameãš
passwordãã£ãŒã«ãã
passwordãŠãããã©ããããã§ãã¯ãã
passwordãããŠããå Žåã¯ãæå¹ãªãŠãŒã¶ãŒåãå
¥åããããšæ°ãããŠãŒã¶ãŒãäœæãããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®äœæ¥ã®ãã®æ®µéã§ã¯ããŠãŒã¶ãŒãšäœæ¥ããããã®APIã¡ãœãããæºåã§ããŠãããšæ³å®ããŠããŸãã
ãã¡ã€ã«BudgetManagerAPI / app / routes / user.js
次ã«ã 
BudgetManagerAPI/app/routesãã©ã«ããŒã«
user.jsãã¡ã€ã«ãäœæããæ¬¡ã®ã³ãŒããæžã蟌ã¿ãŸãã
 const passport = require('passport'),     config = require('@config'),     models = require('@BudgetManager/app/setup'); module.exports = (app) => { const api = app.BudgetManagerAPI.app.api.user; app.route('/api/v1/setup')    .post(api.setup(models.User)) app.route('/api/v1/users')    .get(passport.authenticate('jwt', config.session),  api.index(models.User, app.get('budgetsecret'))); app.route('/api/v1/signup')    .post(api.signup(models.User)); } 
ããã§ã¯ãèªèšŒçšã®
passportã©ã€ãã©ãªãã€ã³ããŒãããæ§æãã¡ã€ã«ãæ¥ç¶ããŠã»ãã·ã§ã³ãã©ã¡ãŒã¿ãŒãæ§æããã¢ãã«ãæ¥ç¶ããããããŠãŒã¶ãŒãAPIãšã³ããã€ã³ããæäœããæš©å©ãæã£ãŠãããã©ããã確èªã§ããŸãã
ãã¹ã
æåã«ã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãšããŒã¿ããŒã¹ãµãŒããŒãå®è¡ããŠãäœæãããã®ã確èªããŸãã ã€ãŸããã¢ãã¬ã¹
httpïŒ// localhostïŒ3001 /ã«ç§»åãããšããµãŒããŒãå®è¡ãããŠããã¿ãŒããã«ãŠã£ã³ããŠã§ããªã¯ãšã¹ãã«é¢ããæ
å ±ïŒãªã¯ãšã¹ããæåããããšãæå³ãã200ïŒã衚瀺ãããŸããå¿çã æ¬¡ã®ããã«ãªããŸãã

ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ãã€ãŸããã©ãŠã¶ã¯ããäºç®ãããŒãžã£ãŒAPIããšããããã¹ããå«ãéåžžã®ããŒãžã衚瀺ããå¿
èŠããããŸãã
httpïŒ// localhostïŒ3001 / api / v1 / authããã¢ã¯ã»ã¹ã§ããã«ãŒã
route確èªããŸãããã
ã¹ããŒã¿ã¹ã404ã®GETãªã¯ãšã¹ãã«é¢ããã¡ãã»ãŒãžããµãŒããŒãŠã£ã³ããŠã«è¡šç€ºãããŸãïŒããã¯ãµãŒããŒã«æ¥ç¶ã§ããããå¿
èŠãªãã®ãæäŸã§ããªãããšã瀺ããŸãïŒããã³å¿çæéã

ããã¯ããã®APIãšã³ããã€ã³ããPOSTãªã¯ãšã¹ãã«ã®ã¿äœ¿çšããŠããããã§ãã GETãªã¯ãšã¹ããå®è¡ããå ŽåããµãŒããŒã«ã¯å¿çãããã®ããããŸããã
httpïŒ// localhostïŒ3001 / api / v1 / usersã«ã¢ã¯ã»ã¹ã㊠ã 
userã«ãŒãã確èªã
ãŸã ã ãµãŒããŒã¯ãã¹ããŒã¿ã¹401ã®GETã¡ãœãããå ±åããŸããããã¯ãã¿ãŒã²ãããªãœãŒã¹ãæäœããããã®ååãªç¹æš©ããªããããèŠæ±ãåŠçãããªãã£ãããšã瀺ããŸãã ã¯ã©ã€ã¢ã³ãã¯ãããã¹ããUnauthorizedããå«ãããŒãžãçºè¡ããŸãã
ããã«ãããèªèšŒã·ã¹ãã ãæ©èœããŠãããšå€æã§ããŸãããããã§ã¯ãç»é²ãã©ãŒã ããæã£ãŠããªãå Žåããã°ã€ã³æ¹æ³ã確èªããæ¹æ³ã«ã€ããŠã®è³ªåãçºçããŸãã
ãã®åé¡ã解決ãã1ã€ã®æ¹æ³ã¯ãPostmanã䜿çšããããšã§ãã éåžžã®ã¢ããªã±ãŒã·ã§ã³ãšããŠ
ããŠã³ããŒãããŠã€ã³ã¹ããŒã«ããããChromeãã©ãŠã¶ãŒã®
æ¡åŒµåœ¢åŒã䜿çšã§ããŸãã
Postmanã䜿çšããã¢ããªã±ãŒã·ã§ã³ã®ãã¹ã
éå§ããã«ã¯ã 
setupãšã³ããã€ã³ãã«æ¥ç¶ããŠç®¡çè
ã¢ã«ãŠã³ããäœæããŸãã Postmanã€ã³ã¿ãŒãã§ãŒã¹ã§ã¯ã次ã®ããã«ãªããŸãã

ã¢ãã¬ã¹ãã£ãŒã«ãã«
http://localhost:3001/api/v1/setupãšå
¥åãããªã¯ãšã¹ãã¿ã€ãã
POST倿ŽããŠã[ 
Send ]ãã¿ã³ãã¯ãªãã¯ããŸãã ãµãŒããŒã®JSONå¿çã«ã¯ãã¡ãã»ãŒãž
"success": trueãå«ãŸããŠããå¿
èŠããããŸãã
次ã«ã管çè
ã¢ã«ãŠã³ãã§ãã°ã€ã³ããŠã¿ãŠãã ããã

ãããè¡ãã«ã¯ããšã³ããã€ã³ã
http://localhost:3001/api/v1/authãžã®POSTãªã¯ãšã¹ãã䜿çšããŠã[ 
Body ]ã¿ãã§åã
adminå€ã§
usernameãš
passwordããŒãèšå®ãã[ 
Send ]ãã¿ã³ãæŒããŸãã
ãµãŒããŒã®å¿çã¯ã次ã®ç»åã®ããã«ãªããŸãã

次ã«ãã·ã¹ãã ãŠãŒã¶ãŒã®ãªã¹ããååŸããŸãã

ãããè¡ãã«ã¯ã 
tokenããŒã®å€ãã³ããŒããGETãªã¯ãšã¹ãã
http://localhost:3001/api/v1/usersããŠãã¢ãã¬ã¹ãã£ãŒã«ãã«
http://localhost:3001/api/v1/usersãšå
¥åãã[ 
Headers ]ã¿ãã§ã 
Bearer token ïŒ 
tokenãªã
token以åã«åä¿¡ãããµãŒããŒå¿çããã³ããŒãããããŒã¯ã³ã貌ãä»ããŸãïŒã åãå Žæã§ãå€
application/x-www-form-urlencodedã®
Content-TypeããããŒã远å ãã 
Sendãã¯ãªãã¯ããŸãã
å¿çã¯JSONé
åã§ããå¿
èŠããããŸããJSONé
åã®å Žåã管çè
ã§ãã1人ã®ãŠãŒã¶ãŒã®ã¿ã«é¢ããæ
å ±ããããŸãã

次ã«ãæ°ãããŠãŒã¶ãŒç»é²æ¹æ³
signup確èªããŸãã

ãããè¡ãã«ã¯ãæ°ããã¿ããéãããšã³ããã€ã³ã
http://localhost:3001/api/v1/signupãžã®POSTãªã¯ãšã¹ããæ§æãã[ 
Body ]ã¿ãã§ã 
x-www-form-urlencodedã¹ã€ãããéžæããæ¬¡ã®å€ãšã¯ç°ãªã
usernameãš
passwordããŒã
passwordãŸã
adminãã¯ãªãã¯ãã[ 
Send ] 
Sendã¯ãªãã¯ããŸãã ãã¹ãŠãæ£åžžã«æ©èœããå Žåãæ¬¡ã®å¿çã衚瀺ãããŸãã

次ã«ã 
http://localhost:3001/api/v1/usersç§»åãã
Postmanã¿ãã«æ»ã£ãŠ
http://localhost:3001/api/v1/usersã®ãªã¹ããååŸãã 
Sendãã¯ãªãã¯ãããšã管çè
ãšæ°ãããŠãŒã¶ãŒã衚ã2ã€ã®ãªããžã§ã¯ãã®é
åãè¿ãããŸãã

ãŸãšã
ããã§ããã®ã·ãªãŒãºã®æåã®ããŒãã¯çµããã§ãã ããã§ã¯ããŒãããNode.jsã¢ããªã±ãŒã·ã§ã³ãäœæããç°¡åãªJWTèªèšŒãã»ããã¢ããããæ¹æ³ãåŠã³ãŸããã æ¬¡ã®ããŒãã§ã¯ãVue.jsã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®éçºãéå§ããŸãã
芪æãªãèªè
ïŒ èè
ã«ãã£ãŠææ¡ãããèè
èªèšŒæ¹æ³ã¯ãæ¬çªç°å¢ã§ã®äœ¿çšã«é©ããŠãããšæããŸããïŒ