采用token加密登录
简单介绍token
1.什么是token,token作用是什么
- (1)token是一段经过后端处理(加密算法)的特殊字符,后端在前端登录时,会返回该字符,前端拿到这个字符后会将其存入cookie
- (2)
- 项目自动登录
- 身份验证
- 前端发送的每一个数据请求,要求携带一个token数据
- 权限验证
- 普通用户
- 会员用户
- 管理员
- 原理:
- 当用户注册并登录后,后端会给它返回一个token字符
- (3)加密软件安装地址
- https://blog.csdn.net/sunhuansheng/article/details/82218678
- 根目录创建了一个rsa文件夹: 用于存放公钥和私钥
- 私钥 -> 加密
- 公钥 -> 解密
JWT【 全称: JsonWebToken 】
-
用户登录 服务器端产生一个token (加密字符串) 发送给前端
-
前端将token 进行保存
-
前端发起数据请求的时候携带token
-
服务端 验证token 是否合法 如果合法继续操作 不合法终止操作
-
token 的使用场景 无状态请求 保持用户的登录状态 第三方登录(token+auth2.0)
产生秘钥私钥
- 安装两个工具
- ActivePerl-5.28.1.2801-MSWin32-x64-24563874.exe
- Win64OpenSSL-1_1_1c.exe
// 1.产生公钥和私钥
//在终端输入下面命令
// 产生私钥 openssl genrsa -out ./private_key.pem 1024 1024 代表私钥长度
//通过openssl生成一段长为1024字节的字符放在private_key.pem文件夹里
// 产生公钥 openssl rsa -in ./private_key.pem -pubout -out ./public_key.pem
//根据rsa文件夹下的private_key.pem文件来输出创建public_key.pem文件
let private_key=fs.readFileSync(path.join(__dirname,'./private_key.pem'))
let public_key=fs.readFileSync(path.join(__dirname,'./public_key.pem'))
var token = jwt.sign(palyload, private_key,{ algorithm: 'RS256'});
后端代码(举一个登录例子)
- router/login.js文件(打造login路由)
const express = require('express') const router = express.Router() const fs = require('fs') const path = require('path') const jwt = require('jsonwebtoken') const { users } = require('../database') //封装的database文件 // 打造login接口 router.route('/login') // 打造了 http://localhost:3000/login .post( async ( req,res,next ) => { // 接收前端发来的数据 console.log('req.body',req.body) // 如果前端的token是空的,那么我们需要返回给它新的token // 如果有,那么自动登录 const { token,username } = req.body //登录请求中携带token if ( !token ) { // 表示token是空的,我们要返回新的给它 // 生成token给它 // 1. 通过fs来读取私钥 const private_key = fs.readFileSync( path.join( __dirname, '../rsa/private_key.pem')) // 2. 通过jsonwebtoken来生成token字符 // jwt.sign( 数据, 私钥, 加密算法配置 ) const token = jwt.sign( username,private_key,{ algorithm: 'RS256' } ) // 进行数据库操作 //users 模块中有一个query方法查询数据库,result是一个对象 const result = await users.query( req.body ) res.render('login',{ data: JSON.stringify({ status: result.status, info: result.info, // [ result.status == 1 && 'token' ]: result.status == 1 && token token: result.status == 1 && token || '用户名密码错误,token不返回' }) }) } }) module.exports = router // 导出模块
- 数据库users集合的操作
const { userSchema } = require('../schema') const model = require('../model') const userModel = model('users', userSchema) const users = { add(data) { // 我现在要将add方法的处理结果返到add函数外面 return new Promise((resolved, rejected) => { // 得到实体 // 判断用户名是否已经存在 userModel.find({}, (err, docs) => { // console.log("docs", docs) // docs 就是数据库查到的结果 [{}] const f = docs.some(item => data.username == item.username) if (f) { // 如果是true,那么数据库是有这个用户名 resolved({ status: 2, info: '用户名已经重复' }) } else { // 数据库没有这个用户名 // 存数据 const userEnity = new userModel(data)//只有add方法需要创建实体 userEnity.save(err => { if (err) { rejected({ status: 0, info: '注册失败' }) } else { resolved({ status: 1, info: '注册成功' }) } }) } }) }) }, del() {}, update() {}, query() {} } module.exports = users
实现自动登录
- 在body中加一个
<body onload=load()>
一进入页面判断是否有tokenfunction load () { const token = cookieUtil.get('TOKEN') if ( token ) { setTimeout(function () { location.href = "./index.html" },2000) } }
mongoose的介绍
- Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用 ,node也是对象,
官方文档https://www.npmjs.com/package/mongoose - 安装mongoose
npm install mongoose -D cnpm i mongoose -D/-S
- 连接数据库之前确保数据库已开启且安装了mongoose包
- 相关名词介绍
- schema(骨架):就相当于定义字段,一个骨架相当于一个表的所有字段,一个数据库有很多表,所有骨架也可以有很多个
- model(模型):由schema生成的模型。个人理解是相当于定义一个集合名称,并将之前所建的这个骨架(理解为字段)放在这个集合中,用于操作数据库
- entity(实体):由model创建的实体,用于数据库的增加
mongoose的使用步骤
-
1、引入mongoose(mongoose是一个对象,对象里有很多方法)
const mongoose=require('mongoose')
-
2、连接数据库
mongoose.connect(dbURL,(err)=>{ if(err){ console.log(err) }else{ console.log('数据库连接成功') } }
- dbURL:一般在本地时是:mongodb://127.0.0.1:27017/数据库名
-
3、创建骨架(定义字段)
//创建骨架,Schema首字母大写,所以是构造函数,要new const userSchema=new mongoose.Schema(); userSchema.Schema({ //定义字段 username:string, password:string })
-
4、创建模型(用于操作除增加以外的数据库操作)
//语法:const userModel=mongoose.model(集合名称(复数形式),骨架) const userModel=mongoose.model("users",userSchema)
-
5、创建实体(实体只有在增加数据时才需要创建)
const user=new userModel();
数据库操作
- 增加:
- const userEnity = new userModel(data);
userEnity.save()
- 删除
user.findById(_id,(err,doc)=>{doc.remove()})
- 修改
user.findById(_id,(err,doc)=>{doc.username="xxx";doc.save()})
- 查询
user.find({},(err,docs)=>{}) //docs的查询结果是一个[{}]