【 Node 】Token的生成与验证、密码的加密与验证

目录结构

【 Node 】Token的生成与验证、密码的加密与验证

搭建服务器

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))
                    });
                });

            }
        })
})

【 Node 】Token的生成与验证、密码的加密与验证
【 Node 】Token的生成与验证、密码的加密与验证

登录

先使用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))
})

【 Node 】Token的生成与验证、密码的加密与验证

携带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
【 Node 】Token的生成与验证、密码的加密与验证
携带token
【 Node 】Token的生成与验证、密码的加密与验证

上一篇:初次尝试GPU Driven —— 大范围植被渲染


下一篇:浅谈DDD(domain-driven design-领域驱动设计)