目录结构
搭建服务器
express框架
mongoose连接数据库
配置passport 方便后面的token验证
server.js
const express = require('express');
const app = express();
const mongoose = require('mongoose');
// 验证token
const passport = require('passport');
// 引入路由
const users = require('./routes/api/users');
// 使用中间件
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// mongodb config
const dbUrl = require('./config/keys').mongoURI;
// mongodb connect
mongoose.connect(dbUrl, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log('数据库连接成功');
})
.catch(err => {
console.log('数据库连接失败', err);
})
// 初始化passport
app.use(passport.initialize());
// 配置passport
require('./config/passport')(passport);
// 使用路由
app.use('/api/users', users)
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
})
注册
使用bcrypt对密码加密
const express = require('express');
const router = express.Router();
// 引入加密模块
const bcrypt = require('bcrypt');
// 引入数据模型
const User = require('../../models/User');
// @route POST api/users/register
// @desc 注册
// @access public
router.post('/register', (req, res) => {
// 检测是否已经注册 查询是否拥有邮箱
User.findOne({ email: req.body.email })
.then((user) => {
if (user) {
return res.status(400).json('邮箱已经被注册')
} else {
// 设置头像
var 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,
identity: req.body.identity,
password: req.body.password
})
// 加密密码
bcrypt.genSalt(10, function (err, salt) {
bcrypt.hash(newUser.password, salt, function (err, hash) {
if (err) throw err;
// 已经加密的密码
newUser.password = hash;
// 存储用户
newUser.save()
.then(user => res.json(user))
.catch(err => console.log(err))
});
});
}
})
})
登录
先使用bcrypt校验密码是否正确
使用jsonwebtokne 生成token
jsonwebtoken
const express = require('express');
const router = express.Router();
// 引入加密模块
const bcrypt = require('bcrypt');
// 引入头像模块
const gravatar = require('gravatar');
// 引入数据模型
const User = require('../../models/User');
// 引入token配置
const jwt = require('jsonwebtoken');
// 引入token配置名字
const Keys = require('../../config/keys');
// @route GET api/users/login
// @desc 登录 返回token
// @access public
router.post('/login', (req, res) => {
const email = req.body.email;
const password = req.body.password;
// 查询邮箱是否存在
User.findOne({ email })
.then(user => {
if (!user) {
return res.status(404).json('邮箱不存在')
}
// 用户存在 检查密码
bcrypt.compare(password, user.password)
.then(isMatch => {
// 密码匹配 配置token
if (isMatch) {
// 定义规则
const rule = { id: user.id, name: user.name, avatar: user.avatar, identity: user.identity };
// jwt.sign('加密规则','加密名字(单独写在其他文件里面在 引入使用)','过期时间(s)',箭头函数)
// 配置token
jwt.sign(rule, Keys.secretOrKey, { expiresIn: 3600 }, (err, token) => {
if (err) throw err;
// 返回token
res.json({
success: true,
token: 'Bearer ' + token
})
})
} else {
return res.status(400).json('密码不匹配')
}
})
})
.catch(err => console.log(err))
})
携带Token获取信息
在server.js里面需要引入 passport并初始化、配置
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: req.user.identity
})
})
passport配置
config / passport.js
// 验证token
const JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
const opts = {}
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
// 引入数据库
const mongoose = require('mongoose');
// 引入数据模型
const User = mongoose.model('users');
// 设置jsonwebtoken的策略
const keys = require('../config/keys');
opts.secretOrKey = keys.secretOrKey;
module.exports = passport => {
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
User.findById(jwt_payload.id)
.then(user => {
if (user) {
return done(null, user);
}
return done(null, false);
})
.catch(err => {
console.log(err);
})
}));
}
不携带token
携带token