1.第一步先用express命令创建一个空白项目
express demo //创建项目
cd demo //进入项目
cnpm install //安装依赖
npm start //启动项目
访问 `http://localhost:3000`
看到
`Express
Welcome to Express`
即为成功!
2.npm start 可以启动项目,这里我们安装一个插件nodemon,实现修改自动热更新
cnpm install nodemon
安装成功后,执行
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`
即为成功!
3.下面开始准备链接mongodb数据库,先在根目录新建一个文件夹config
根路径下敲
`mkdir config`
新建成功!
然后在`config`文件夹下新建`keys.js`文件
keys.js内这样写:
module.exports = {
mongoURL: "mongodb://aoaoe:[email protected]/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(手机号) 发送短信验证码
* 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 = ""; //统一改名: 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") { // 短信发送成功
// 保存验证码
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
}
- 接下来我们分析下,如何建表,表与表之间什么关系,既然要实现动态路由权限管理。那么菜单就要交给后端来管理,所以,
首先要有一个菜单表(menu)和一个商家(后台用户)表(boss)
,然后 继续往下想,菜单应该绑定一个角色,(这就要有一个角色表:role)
而商家要和角色相绑定,(这时候要有一个关系表,商家和角色绑定的关系表:bossRelationRole)
而角色要分配一些菜单,就是分配权限的意思,商家和这个角色绑定了,那么商家就拥有该角色所拥有的一些菜单,也可以说是权限也可以说是路由,这样,商家登录后台,后端返回角色拥有的路由菜单权限,后台动态渲染,这样就实现了 动态路由 的目的。
- 通过上面的分析,我们得知,一共要有
四个表
,菜单表menu
,商家表boss
,角色表role
,商家角色关系表bossRelationRole
12.下面开始建模型,在根路径下新建文件夹
models
,models文件夹下新建4个js文件,Boss.js
Menu.js
Role.js
BossRelationRole.js
,内容如下