1.第一步先用express命令創(chuàng)建一個空白項目
express demo //創(chuàng)建項目
cd demo //進入項目
cnpm install //安裝依賴
npm start //啟動項目
訪問 `http://localhost:3000`
看到
`Express
Welcome to Express`
即為成功!
2.npm start 可以啟動項目,這里我們安裝一個插件nodemon,實現修改自動熱更新
cnpm install nodemon
安裝成功后,執(zhí)行
nodemon
看到終端
[nodemon] 1.18.8
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./bin/www`
訪問 `http://localhost:3000`
看到
`Express
Welcome to Express`
即為成功!

express目錄結構
3.下面開始準備鏈接mongodb數據庫,先在根目錄新建一個文件夾config
根路徑下敲
`mkdir config`
新建成功!
然后在`config`文件夾下新建`keys.js`文件
keys.js內這樣寫:
module.exports = {
mongoURL: "mongodb://aoaoe:888888@it98k.cn/aoaoe"
//暴露出一個url:“mongodb://賬號:密碼@域名或者ip/集合名稱(庫名)”
}
4.安裝mongoose
根路徑下敲
`cnpm install mongoose --save`
package.json文件內可以看到版本號,即為成功!
- 打開app.js文件引入mongoose和keys.js
var mongoose = require("mongoose");
var db = require("./config/keys.js").mongoURL
6.下面開始鏈接mongodb數據庫,在上面兩行代碼下敲鏈接數據庫的代碼,不做解釋了,想了解的百度下
mongoose.connect(db, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false })
.then((res) => {
console.log("遠程數據庫連接成功~~")
}).catch((err) => {
console.log(err)
});
終端打印出
[nodemon] restarting due to changes...
[nodemon] starting `node ./bin/www`
遠程數據庫連接成功~~
即為鏈接成功!!!
- 為了以后的方便,express設置允許跨域訪問,app.js插入這段代碼,要在
var app = express();
這行代碼下面插入
var app = express();
//express 設置允許跨域訪問
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,X-File-Name,authorization");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("Content-Type", "application/json;charset=utf-8");
res.header("X-Powered-By", ' 3.2.1');
res.header("Cache-Control", "no-store");
if (req.method == 'OPTIONS') {
res.sendStatus(200).end();
} else {
next();
}
});
8.因為要用到md5加密 和 token驗證和阿里云短信 所以,先裝上
jsonwebtoken和blueimp-md5和@alicloud/pop-core
cnpm install blueimp-md5 jsonwebtoken --save
package.json文件內可以看到相應版本號,即為成功!
9.根路徑下新建utils文件夾,utils文件夾內新建兩個js文件
sms.js、token.js
sms.js
/**
* sms.send(手機號) 發(fā)送短信驗證碼
* sms.verify(手機號,驗證碼) 校驗驗證碼是否正確
**/
const Core = require('@alicloud/pop-core');
// 阿里云控制臺 - 短信服務 - 國內消息
const SignName = "SignName"; //換成你自己的
const TemplateCode = "TemplateCode";//換成你自己的
// https://usercenter.console.aliyun.com/
const accessKeyId = "accessKeyId";//換成你自己的
const accessKeySecret = "accessKeySecret";//換成你自己的
var client = new Core({
accessKeyId,
accessKeySecret,
endpoint: 'https://dysmsapi.aliyuncs.com',
apiVersion: '2017-05-25'
});
// 保存手機號和驗證碼的對應關系
// phone_code_list = {'18855551234':['1024']}
var phone_code_list = {};
exports.send = function(phone) {
function randomCode(length) {
var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
var result = ""; //統(tǒng)一改名: alt + shift + R
for (var i = 0; i < length; i++) {
var index = Math.ceil(Math.random() * 9);
result += chars[index];
}
return result;
}
// 生成驗證碼
// var code = "" + _.random(9) + _.random(9) + _.random(9) + _.random(9);
var code = randomCode(6);
console.log(code);
return new Promise((resolve, reject) => {
try {
client.request('SendSms', {
RegionId: "cn-hangzhou",
PhoneNumbers: phone,
SignName,
TemplateCode,
TemplateParam: "{code:" + code + "}"
}, {
method: 'POST'
}).then((result) => {
if (result.Message && result.Message == "OK" && result.Code && result.Code == "OK") { // 短信發(fā)送成功
// 保存驗證碼
if (phone_code_list[phone]) {
phone_code_list[phone].push(code);
} else {
phone_code_list[phone] = [code];
}
// 三分鐘后刪除驗證碼
setTimeout(() => {
_.pull(phone_code_list[phone], code);
if (phone_code_list[phone] && phone_code_list[phone].length == 0) {
delete phone_code_list[phone];
}
}, 3 * 60 * 1000)
resolve(result)
} else {
reject(result)
}
}, (ex) => {
reject(ex)
})
} catch (error) {
reject(error)
}
})
}
exports.verify = function(phone, code) {
if (phone_code_list[phone] != undefined) {
return (phone_code_list[phone].indexOf(code) > -1)
} else {
return false
}
}
token.js
var jwt = require('jsonwebtoken');
var jwtScrect = 'aoaoe'; //簽名
//登錄接口 生成token的方法
var setToken = function(_id, loginame, identity, phone) {
return new Promise((resolve, reject) => {
//expiresln 設置token過期的時間
//{ loginame: loginame, _id: _id } 傳入需要解析的值( 一般為用戶名,用戶id 等)
const rule = { _id: _id, loginame: loginame, identity: identity, phone: phone };
// const token = 'Bearer ' + jwt.sign(rule, jwtScrect, { expiresIn: '36000' });
const token = jwt.sign(rule, jwtScrect, { expiresIn: '1day' });
resolve(token)
})
}
//各個接口需要驗證token的方法
var getToken = function(token) {
return new Promise((resolve, reject) => {
if (!token) {
console.log('token是空的')
reject({
error: 'token 是空的'
})
} else {
//第二種 改版后的
var info = jwt.verify(token, jwtScrect);
resolve(info); //解析返回的值(sign 傳入的值)
}
})
}
module.exports = {
setToken,
getToken
}
- 接下來我們分析下,如何建表,表與表之間什么關系,既然要實現動態(tài)路由權限管理。那么菜單就要交給后端來管理,所以,
首先要有一個菜單表(menu)和一個商家(后臺用戶)表(boss),然后 繼續(xù)往下想,菜單應該綁定一個角色,(這就要有一個角色表:role)而商家要和角色相綁定,(這時候要有一個關系表,商家和角色綁定的關系表:bossRelationRole)而角色要分配一些菜單,就是分配權限的意思,商家和這個角色綁定了,那么商家就擁有該角色所擁有的一些菜單,也可以說是權限也可以說是路由,這樣,商家登錄后臺,后端返回角色擁有的路由菜單權限,后臺動態(tài)渲染,這樣就實現了 動態(tài)路由 的目的。
- 通過上面的分析,我們得知,一共要有
四個表,菜單表menu,商家表boss,角色表role,商家角色關系表bossRelationRole
12.下面開始建模型,在根路徑下新建文件夾
models,models文件夾下新建4個js文件,Boss.jsMenu.jsRole.jsBossRelationRole.js,內容如下