步骤:
1.node安装
2.npm init 初始化项目
3.安装项目使用到的node框架
npm install express
let express = require('express');
let app = new express();
/*
为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
*/
const port = process.env.PORT || 5000;
// 拦截get请求
app.get('/', (req, res) => {
/*
res.send('响应内容');服务器端有数据返回到客户端
res.end();终结响应处理流程
res.end() 只接受服务器响应数据,如果是中文则会乱码
res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
*/
res.send('你好!express')
})
// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
res.send("Error!" + err.message);
})
// 监听启动服务器
app.listen(port, () => {
console.log(`Server running http://localhost:${port}`)
});
配置启动js的命令:
并在package.json文件scripts属性下配置cdm命令(启动node server.js)
"start": "node server.js/项目入口js",
dm命令行中输入:npm run start 启动项目
浏览器上输入:
4.全局安装node热加载(实时监听js文件的改动 更新)
npm install nodemon -g
并在package.json文件scripts属性下配置cdm命令(热启动node server.js)
"server": "nodemon server.js/项目入口js"
cdm命令行中输入:npm run server 启动
5.操作数据库
5.1安装mongodb数据库
npm install mongoose
5.1.1 Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块
5.1.2 Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装
5.1.3 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处
5.1.4 基于MongoDB驱动,通过关系型数据库的思想来实现非关系型数据库。
5.2安装数据库可视化工具MongoDB Compass Community
6.通过Node来操作MongoDB数据库的一个模块(mongoose)
测试:
/config/keys.js(配置url文件)
module.exports = {
mongoURL: "mongodb://127.0.0.1:27017"
}
let express = require('express');
let app = new express();
let mongoose = require('mongoose');
/*
为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
*/
const port = process.env.PORT || 5000;
// DB config
const db = require('./config/keys').mongoURL;
// Connect to mongodb
mongoose.connect(db)
.then(() => console.log('MongoDB Connected Success'))
.catch((err) => console.log(err))
// 拦截get请求
app.get('/', (req, res) => {
/*
res.send('响应内容');服务器端有数据返回到客户端
res.end();终结响应处理流程
res.end() 只接受服务器响应数据,如果是中文则会乱码
res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
*/
res.send('你好!express')
})
// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
res.send("Error!" + err.message);
})
// 监听启动服务器
app.listen(port, () => {
console.log(`Server running http://localhost:${port}`)
});
6.2 开发测试接口
express----路由的使用
/routes/api/users.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入口文件中引入api接口
// 引入users.js
const users = require('./routes/api/users');
// 中间件使用routes
app.use('/api/users', users)
获取post表单的中间件body-parser
npm install body-parser
注意:配置要放在接口之前
body-parser 中间件 第三方的 获取 post 提交的数据
1.npm install body-parser --save
2.const bodyParser = require('body-parser')
3.设置中间件(注意这里要放到路由/api中间件前面)
//处理 form 表单的中间件
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false })); form 表单提交的数据
// parse application/json
app.use(bodyParser.json()); 接受json 类型的数据
4.req.body 获取数据
/*
server.js入口文件
使用body-parser中间件
此部分要放在路由中间件前面
*/
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
密码加密bcrypt (哪个api需要在哪个文件引入)
npm install bcrypt
const bcrypt = require('bcrypt');
//saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
bcrypt.genSalt(saltRounds = 10, function (err, salt) {
bcrypt.hash(newUser.password, salt, function (err, hash) { // 需要加密
if (err) throw err;
newUser.password = hash;
// 保存文档(mongoose提供)
newUser.save()
.then(user => res.json(user))
.catch(err => console.log)
});
});
实战:实现注册页api
数据库的字段:/models/User.js
// 操作数据库字段配置
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema(创建字段)
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
avatar: {
type: String
},
password: {
type: String,
required: true
},
date: {
type: Date,
default:Date.now(), //返回创建时间戳
},
})
/*
Model 代表的是数据库中的集合,通过Model才能对数据库进行操作
第一个参数要映射的集合名;第二个创建的约束(Schema对象)
*/
module.exports = User = mongoose.model('users',UserSchema);
api接口实现:/routes/api/user.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');
const User = require('../../models/User'); // 操作数据库字段配置
/*
$route GET api/users/test
@desc 返回请求的json数据
@access public
*/
router.get('/test', (req, res) => {
res.json({ msg: "login works" })
})
/*
$route POST api/users/register
@desc 返回请求的json数据
@access public
*/
router.post('/register', (req, res) => {
console.log(req.body)
// 查询数据库中是否有这个人
User.findOne({ email: req.body.email })
.then((user) => {
if (user) {
return res.status(400).json({ name: "用户已被注册!" });
} else {
// return res.json('用户注册中...')
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
//saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
bcrypt.genSalt(saltRounds = 10, function (err, salt) {
bcrypt.hash(newUser.password, salt, function (err, hash) { // 需要加密
if (err) throw err;
newUser.password = hash;
// 保存文档(mongoose提供)
newUser.save()
.then(user => res.json(user))
.catch(err => console.log)
});
});
}
})
})
module.exports = router;
加密补充知识:
/*
生成加密
bcrypt.genSalt() 加密
saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
*/
bcrypt.genSalt(saltRounds = 10, function(err, salt) {
bcrypt.hash(req.body.password, salt, function(err, hash) {
if (err) throw err;
newUser.password = hash;
// 保存文档(mongoose提供)
newUser.save()
.then(user => res.json(user))
.catch(err => console.log(err))
});
});
/*
解析加密的字段
*/
bcrypt.compare(当前密码, 存储密码, function(err, result) {
}
server.js入口
let express = require('express');
let mongoose = require('mongoose');
let bodyParser = require('body-parser'); // 解析请求体
/*
为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
*/
const port = process.env.PORT || 5000;
let app = new express();
// DB config
const db = require('./config/keys').mongoURL;
// Connect to mongodb
mongoose.connect(db)
.then(() => console.log('success'))
.catch((err) => console.log(err))
/*
使用body-parser中间件
此部分要放在路由中间件前面
*/
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// 引入users.js
const users = require('./routes/api/users');
// 中间件使用routes
app.use('/api/users', users)
// 拦截get请求
app.get('/', (req, res) => {
/*
res.send('响应内容');服务器端有数据返回到客户端
res.end();终结响应处理流程
res.end() 只接受服务器响应数据,如果是中文则会乱码
res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
*/
res.send('你好!express')
})
// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
res.send("Error!" + err.message);
})
// 监听启动服务器
app.listen(port, () => {
console.log(`Server running http://localhost:${port}`)
});
7.安装postman软件测试api
在MongoDB Compass Community可视化工具上查看是否添加成功:
全球公认头像的使用:(辅助)
npm install gravatar
/*
http://www.gravatar.com/avatar/参数1?s=参数2&d=参数3&r=参数4
参数1:在Gravatar网站上注册的邮箱的MD5值
参数2:指的是图片的大小,自定义参数,整数
参数3:如果为identicon,随机显示图纹图片,默认显示蓝底白字G图片
参数4:图片类型。(G 普通级、PG 辅导级、R 和 X 为限制级),不过一般情况下都是G
gravatar.url(邮箱,{图片大小,图片类型,默认})
*/
let avatar = gravatar.url(req.body.email, { s: '200', r: 'pg', d: 'mm' });
api接口实现:/routes/api/user.js
const gravatar = require('gravatar'); // 公共头像
/*
$route POST api/users/register
@desc 返回请求的json数据
@access public
*/
router.post('/register', (req, res) => {
// 查询数据库中是否存在这个人
let { email } = req.body;
User.findOne({ email }).then(user => {
if (user) {
return res.status(404).json('用户已注册')
} else {
/*
http://www.gravatar.com/avatar/参数1?s=参数2&d=参数3&r=参数4
参数1:在Gravatar网站上注册的邮箱的MD5值
参数2:指的是图片的大小,自定义参数,整数
参数3:如果为identicon,随机显示图纹图片,默认显示蓝底白字G图片
参数4:图片类型。(G 普通级、PG 辅导级、R 和 X 为限制级),不过一般情况下都是G
gravatar.url(邮箱,{图片大小,图片类型,默认})
*/
let avatar = gravatar.url(req.body.email, { s: '200', r: 'pg', d: 'mm' });
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
avatar,
identity: req.body.identity,
})
/*
bcrypt.genSalt() 加密
saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
*/
bcrypt.genSalt(saltRounds = 10, function(err, salt) {
bcrypt.hash(req.body.password, salt, function(err, hash) {
if (err) throw err;
newUser.password = hash;
// 保存文档(mongoose提供)
newUser.save()
.then(user => res.json(user))
.catch(err => console.log(err))
});
});
}
}).catch(err => {
if (err) throw err;
})
})
8. 开发登录接口
登录token(token相当于是一个识别令牌,只有拿到这个令牌才能获取到其他的信息),相当于是一个权限
生成token
npm install jsonwebtoken
验证token
npm install passport
npm install passport-jwt
/routes/api/user.js
const jwt = require('jsonwebtoken'); // 生成 JWT 字符串(token)
const keys = require('../../config/keys'); //
const passport = require('passport'); // 验证token
/*
$route POST api/users/login
@desc 返回token jwt passport
@access public
*/
router.post('/login', (req, res) => {
const { email, password } = req.body;
// 查询数据库
User.findOne({ email }).then(user => {
if (!user) {
return res.status(404).json("用户不存在!请注册用户")
}
// 密码匹配
bcrypt.compare(password, user.password, (err, result) => {
// console.log(password, user.password, result);
if (result) {
/*
jwt.sign(规则, token密钥,过期时间, 箭头函数)
返回token
*/
const rule = {
id: user.id,
name: user.name,
avatar: user.avatar,
identity: user.identity
}
let token = jwt.sign(rule, keys.secretOrKey, { expiresIn: 60 * 60 * 1000 }, (err, token) => {
if (err) {
throw err;
} else {
// "Bearer "固定
res.json({
success: true,
token: "Bearer " + token
})
}
})
} else {
return res.status(400).json('密码错误!')
}
})
})
})
生成token说明
/*
jwt.sign(规则, token密钥,过期时间, 箭头函数)
返回token
*/
const rule = {
id: user.id,
name: user.name,
avatar: user.avatar,
identity: user.identity
}
let token = jwt.sign(rule, keys.secretOrKey, { expiresIn: 60 * 60 * 1000 }, (err, token) => {
if (err) {
throw err;
} else {
// "Bearer "固定
res.json({
success: true,
token: "Bearer " + token
})
}
})
/config/keys.js
module.exports = {
mongoURL: "mongodb://127.0.0.1:27017",
secretOrKey: "secret", // token 密钥配置
}
在postman进行测试:
9. 开发携带 token 请求头信息,获取用户信息
server.js 配置解析token的中间件
const passport = require('passport'); // 验证token
// passport初始化(验证token,解析 token,路由前)
app.use(passport.initialize());
require('./config/passport')(passport);
/routes/api/user.js
/*
$route GET api/users/current
@desc 返回当前用户(测试携带 token 获取当前的用户)
@access private
需在headers带上token验证
passport.authenticate(验证方式)
禁用会话 Disable Sessions
*/
router.get('/current', passport.authenticate('jwt', { session: false }), (req, res) => {
// res.json({msg: "current success"});
// 返回用户信息
res.json({
id: req.user.id,
name: req.user.name,
email: req.user.email,
identity: req.user.identity
});
})
在postman进行测试: