视频课程地址:https://www.bilibili.com/video/av59056478
资金管理系统带权限(node/element/vue)
目录
Node接口搭建
express搭建服务器
1.首先在本地新建一个存放项目的文件夹
2.cd到项目文件夹,输入npm init命令,初始化一个node项目,会生成一个package.json文件,包含了对项目的简介,并指定了入口文件(“main”: “server.js”,可自己设置其他名称)
3.在项目根目录下新建入口文件:server.js
4.搭建本地服务器需要用到express框架,打开终端,输入 npm install express
安装即可,安装完成之后就可以正常使用了
5.
// 引入express
const express = require("express");
// 实例化一个app
const app = express();
// 设置一个端口号,本地环境下是5000
const port = process.env.PORT || 5000;
// 对端口进行监听
app.listen(port, ()=>{
console.log(`server running on port ${port}`);
})
完成之后,在控制台执行 node server.js
可看到输出信息,这时候它已经将当前的项目运行了,运行之后通过浏览器去访问是访问不到的,因为我们没有设置任何路由。
设置一个路由测试一下:
// 引入express
const express = require("express");
// 实例化一个app
const app = express();
// 设置路由
app.get("/", (req, res) => {
res.send("Hello World");
})
// 设置一个端口号,本地环境下是5000
const port = process.env.PORT || 5000;
// 对端口进行监听
app.listen(port, ()=>{
console.log(`server running on port ${port}`);
})
现在就可以通过浏览器来访问了,但是访问之前需要重新执行一下 node server.js
才会生效,因为我们对代码做了修改。
这种每次手动执行更新的方式有些繁琐,我们可以使用nodemon实现在代码发生改变时自动更新,只需要执行npm install nodemon -g
即可全局安装
连接MongoDB数据库
mongodb教程参考:http://www.jspang.com/posts/2017/12/16/mongodb.html
1.在项目中使用本地的mongodb数据库,在配置之前我们需要开启本地的mongodb服务
2.在根目录下创建一个config文件夹,新建db.js,用于存放数据库相关的信息
// 数据库名称:node-app-db
module.exports = app => {
const mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1:27017/node-app-db",{
useNewUrlParser: true,
useUnifiedTopology: true
}).then(()=>console.log("MongoDB Connected"))
.catch(error => console.log(error))
}
3.在server.js中引入数据库的配置
// 搭建服务器
const express = require("express");
// 实例化一个app
const app = express();
// 设置路由
app.get('/', (req, res)=>{
res.send("Hello World");
})
// 连接数据库
require('./config/db')(app);
4.保存代码之后,控制台会打印如下信息:
说明数据库已经连接成功了
搭建路由和数据模型并存储数据到数据库
路由其实就是我们需要访问的接口地址。 在项目根目录下创建文件夹routes->api,然后在api下创建新建文件:users.js,用于编写与用户相关的接口。
例:
user.js
const express = require("express");
const router = express.Router();
// $route GET /api/users/test
// @desc 返回请求的json数据
// @access public(公有接口)
router.get('/test', (req, res)=>{
res.json({msg:"login works"})
})
module.exports = router;
server.js
const express = require("express");
const app = express();
// 引入user.js
const users = require("./routes/api/users.js");
// 使用路由
app.use("/api/users", users);
// 连接数据库
require('./config/db')(app);
// 本地环境下是5000
const port = process.env.PORT || 5000;
app.listen(port, ()=>{
console.log(`server running on port ${port}`);
})
访问:http://localhost:5000/api/users/test
在项目根目录下创建一个models文件夹,然后新建一个User.js文件,用于存放User数据模型
User.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// crates schema
const UserSchema = new Schema({
nam:{type: String, required: true},
email:{type:String, required: true},
password: {type: String, required: true},
avatar: {type: String},
date: {type: Date, default: Date.now}
});
module.exports = User = mongoose.model("users", UserSchema);
安装一个测试接口的工具: postman
完成后用上面的接口地址测试一下:在users.js中写一个注册接口,
// @route POST api/users/register
// @desc 返回请求的json数据
// @access public接口,如果要返回token的话则是私有接口
router.post('/register', (req, res)=>{
console.log(req.body);
})
它是一个post请求,需要安装一个第三方模块body-parser
npm install body-parser
然后在server.js中引入
const bodyParser = require("body-parser");
// 使用bodyParser中间件
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
urlencoded是为了解决post请求下的x-www-form-urlencoded
测试一下接口:
因为没有返回内容,所以在postman的控制台看不到信息,但在终端可以看到打印的信息:
新增需求: 查询邮箱是否存在,如果注册的邮箱已在数据库中存在,则返回相应的错误提示;否则成功添加到数据库中
一些准备:
用户的密码加密,需要一个第三方插件:npm install bcrypt
在users.js中加入代码:
const User = require("../../models/User.js");
const bcrypt = require("bcrypt"); // 加密
// @route POST api/users/register
// @desc 返回请求的json数据
// @access public接口,如果要返回token的话则是私有接口
router.post('/register', (req, res)=>{
// 查询数据库该邮箱是否存在
User.findOne({email: req.body.email})
.then((user) => {
if(user){
return res.status(400).json("邮箱已被注册!")
} else {
const newUser = new User({
name: req.body.name,
email:req.body.name,
password:req.body.password
});
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.password, salt, (err, hash)=>{
if(err) throw err;
newUser.password = hash; // hash是已经加密后的密码
newUser.save()
.then(user=>res.json(user))
.catch(err=>console.log(err));
})
})
}
})
})
测试:
第一次提交
再次提交:
查看数据库:
数据已经成功保存了
使用全球公认头像gravatar
参考:https://www.npmjs.com/search?q=gravatar
安装:npm install gravatar
在users.js中引入
const gravatar = require('gravatar');
......
// 邮箱未被注册,则提交用户的相关信息
......
const avatar = gravatar.url(req.body.email, {s:'200', r:'pg', d: 'mm'});
const newUser = new User({
name: req.body.name,
email:req.body.email,
avatar, // 头像
password:req.body.password,
});
......
测试:
复制avatar的地址访问之后会得到一个图片,这就是"mm"返回给我们的图片,如果在gravatar注册了这个邮箱的话,则会返回在gravatar网站中使用的头像图片
搭建登录接口
参考:https://www.npmjs.com/search?q=bcrypt
安装:npm install bcrypt
(可用于密码匹配)
users.js中添加登录接口代码:
// @route POST api/users/login
// @desc 返回token (会用到jwt passport)
// @access public接口,如果要返回token的话则是私有接口
router.post('/login', (req, res)=>{
const email = req.body.email;
const name = req.body.name;
const password = req.body.password;
// 查询数据库
User.findOne({email:email})
.then(user=>{
if(!user){
return res.status(404).json({"email": "用户不存在"});
}
// 密码匹配
bcrypt.compare(password, user.password)
.then(isMatch=>{
if(isMatch){
res.json({"msg":"success"});
} else {
return res.status(404).json({"password": "密码错误"})
}
})
})
})
测试:可根据不同的情况填写参数进行测试
修改代码,使得登录成功之后返回的是token
参考:https://www.npmjs.com/package/jsonwebtoken
安装:npm install jsonwebtoken
加密名称单独设置一个文件keys.js放在config文件夹下
keys.js
module.exports = {
secretOrKey:"secret"
};
密码匹配部分做些修改:
const jwt = require('jsonwebtoken');
const keys = require("../../config/keys.js");
......
// 密码匹配
bcrypt.compare(password, user.password)
.then(isMatch => {
if(isMatch){
// jwt.sign("规则","加密名称","过期时间","箭头函数")
const rule = {
id:user.id,
name:user.name,
avatar:user.avatar
};
jwt.sign(rule, keys.secretOrKey, {expiresIn:3600},(err, token)=>{
if(err) throw err;
res.json({
success:true,
token:"wu"+token
});
})
}else{
return res.status(400).json({"password": "密码错误"});
}
})
测试:
使用passport-jwt验证token
token可以理解令牌,或者说钥匙。通过用户名和密码登录之后会返回一个token,可以拿着这个token去请求一些数据。如果没有这个token或者token已经过期的话,就得不到想要的数据了。
参考:
https://www.npmjs.com/package/passport-jwt https://www.npmjs.com/package/passport
安装:npm install passport-jwt passport
(用于验证token)
在users.js中引入:
const passport = require("passport");
在server.js中对passport进行初始化(初始化之后才可以被使用)
// passport的初始化
app.use(passport.initialize());
还需要对passport进行一些配置,单独建一个passport.js文件放在config下:
passport.js
const JwtStrategy = require("passport-jwt").Strategy,
ExtractJwt = require("passport-jwt").ExtractJwt;
const mongoose = require("mongoose");
const User = mongoose.model("users"); // 数据库表的名字
const keys = require("../config/keys.js");
const opts = {}
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
module.exports = passport => {
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
console.log(jwt_payload);
}));
}
配置完成后还需要在server.js中引入
const passport = require("passport");
......
// passport的初始化
app.use(passport.initialize());
require('./config/passport.js')(passport);
在users.js中加入token验证:
// @route POST api/users/current
// @desc 返回当前用户的信息
// @access private
// router.get("/current", "验证token", "箭头函数")
router.get("/current", passport.authenticate("jwt", {session:false}),
(req, res)=>{
res.json({msg: "success"});
});
测试
返回的是一个"Unauthorized", 原因是请求的时候没有给它添加token。
现在使用一个有效账号登录之后,复制得到的token值,在请求头中加入token
点击send之后得到的还是"Unauthorized",返回的token值的前缀一定要是一个固定的名字,名称已经配置好了,必须是"Bearer "
// token:"wu"+token
// 修改为
token:"Bearer "+token
重新登录获取新的token值,填入请求头中,再点击send可在终端看到打印信息(没有返回值,所在postman的控制台看不到):
修改一下passport.js
module.exports = passport => {
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
// console.log(jwt_payload);
User.findOne({id: jwt_payload.sub}, (err, user) => {
User.findById(jwt_payload.id)
.then(user => {
if(user){
return done(null, user);
}
return done(null, false);
})
.catch(err => console.log(err));
});
}));
}
修改一下users.js:
// @route POST api/users/current
// @desc 返回当前用户的信息
// @access private
// router.get("/current", "验证token", "箭头函数")
router.get("/current", passport.authenticate("jwt", {session:false}),
(req, res)=>{
res.json({
id:req.user.id,
name:req.user.name,
email:req.user.email
});
});
测试:
增加身份字段及接口调试
在之后的项目中,会有关于用户身份的区别,所以我们需要再增加一个身份字段identity
models/User.js中增加
routes/api/users.js中增加
测试:
注册测试:
登录测试:
请求当前用户信息测试: