Node中使用token(基于第三方包jsonwebtoken)
Posted 小小白学计算机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node中使用token(基于第三方包jsonwebtoken)相关的知识,希望对你有一定的参考价值。
一、jsonwebtoken 用于生成token(加密)
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
-
安装:
npm i passport-jwt passport --save
-
在server.js 入口文件中,引入passport
-
初始化passport,并引入passport.js文件
-
在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做如下修改:
- 注册时,填写identify身份字段,注册成功后返回用户的基本信息:
- 用户输入正确的email和password成功登录之后,给前端返回token
- 前端请求需要登录之后才能访问的接口时,需要在请求头中加上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)的主要内容,如果未能解决你的问题,请参考以下文章