視頻課程地址: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中增加
測試:
註冊測試:
登錄測試:
請求當前用戶信息測試: