Node中使用token(基于第三方包jsonwebtoken)

Posted 小小白学计算机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node中使用token(基于第三方包jsonwebtoken)相关的知识,希望对你有一定的参考价值。

一、jsonwebtoken 用于生成token(加密)

> jsonwebtoken

1. 安装

npm i jsonwebtoken --save

2. 使用

2.1 引入

在这里插入图片描述

2.2 加密

用户登录成功后,后端生成token,返回给前端
在这里插入图片描述

在这里插入图片描述

二、passport、passport-jwt 用于验证token(解密)

passport-jwt和passport中间件来验证token
passport-jwt是一个针对jsonwebtoken的插件,passport是express框架的一个针对密码的中间件
passport-jwt

  1. 安装: npm i passport-jwt passport --save

  2. 在server.js 入口文件中,引入passport
    在这里插入图片描述

  3. 初始化passport,并引入passport.js文件
    在这里插入图片描述
    在这里插入图片描述

  4. 在passport.js文件中,具体配置passport
    在这里插入图片描述

const JwtStrategy = require('passport-jwt').Strategy,
    ExtractJwt = require('passport-jwt').ExtractJwt;
// const mongoose = require("mongoose");
const {User} = require('../models/User.js')
// 引入keys, 拿到secret
const keys = require('../config/db.js')
const opts = {}
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;

module.exports = (passport) => {

    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        console.log(jwt_payload)
    }));
}

1)请求/current时,请求体带上token的情况:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
2)请求/current时,请求头没有带上token的情况:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在users表中,添加一个字段用于权限认证,
在这里插入图片描述
然后接口代码users.js做如下修改:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 注册时,填写identify身份字段,注册成功后返回用户的基本信息:
    在这里插入图片描述
  2. 用户输入正确的email和password成功登录之后,给前端返回token
    在这里插入图片描述
  3. 前端请求需要登录之后才能访问的接口时,需要在请求头中加上token,携带上token信息,否则无法拿到接口返回的数据。
    在这里插入图片描述
// 登录 注册模块
const express = require("express")
const router = express.Router()
const bcrypt = require("bcrypt")
const gravatar = require('gravatar')
const jwt = require('jsonwebtoken')
const keys = require('../../config/db.js')

const passport = require('passport')

const User = require('../../models/User')

router.get("/test", (req, res) => {
    res.json({ msg: "login works" })
})

// 注册接口
router.post("/register", (req, res) => {
    console.log(req.body)

    // 查询数据库中是否存在该email的用户
    User.findOne({
        email: req.body.email
    }).then((user) => {
        if (user) {
            return res.status(400).json({ msg: "邮箱已被注册" })
        } 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: avatar,
                password: req.body.password,
                identify: req.body.identify
            })

            // 对密码进行加密
            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)
                    })
                });
            });
        }
    })
})

// 登录接口, 返回token  jwt passport
router.post("/login", (req, res) => {
    const email = req.body.email
    const password = req.body.password

    // 根据email查询,数据库中是否存在该用户
    User.findOne({
        email: email
    }).then((user) => {
        if (!user) {
            return res.status(404).json({msg: '用户不存在!'})
        }
        // 用户存在,则检查密码是否一致
        bcrypt.compare(password, user.password).then((isMatch) => {
            if (isMatch) {
                const rule = {
                    id: user.id, 
                    name: user.name,
                    avatar: user.avatar,
                    identify: user.identify
                }
                jwt.sign(rule, keys.secretOrKey, {expiresIn: 3600}, (err, token) => {
                    if (err) throw err;
                    return res.json({
                        success: true,
                        token: "Bearer " + token
                    })
                })
            } else {
                return res.status(400).json({msg: '密码错误!'})
            }
        })

    })

})


// 登录后才能访问的接口
router.get("/current", passport.authenticate('jwt', {session: false}), (req, res) => {
    const {_id ,name, email, avatar, identify, date} = req.user
    res.json({
        id: _id,
        name: name,
        email: email,
        avatar: avatar,
        identify: identify,
        date: date
    })
})

module.exports = router

以上是关于Node中使用token(基于第三方包jsonwebtoken)的主要内容,如果未能解决你的问题,请参考以下文章

初识npm

基于token机制鉴权架构

Node中require第三方模块的规则

小程序中基于token的登录流程

基于Token的WEB后台认证机制

使用蓝鲸平台登录态验证接入第三方系统