用node.js做后台模拟登录时密码md5加密以及带上token数据传输

登录一般是怎么做的
  • 首先后台会给前台一个接口,前台进行测试。对密码进行md5不可逆的加密,有时用户的秘密会比较简单,我会对自己定义一些规则进行二次加密,比如翻转两次。
  • 后台会对用户名秘密进行判断,验证通过后,后台会基于用户名id时间用aes加密,返回一个token字符串。
  • 前台会token进行保存到本地stronge。
  • 使用axios进行请求数据,将axios进行封装 每次请求时都会将token带到后台去,放在headers里 后台进行检测是否合法 合法就会返回想要的数据
  • 如果有需求记住密码的,就在登录成功后将密码存到本地,页面加载时候找到存在本地的信息localStorage.getItem(“login_name”)
  • 如果没有要求记住密码sessionStorage.setItem(“login_name”,username)零时存储
  • 在退出时,将储存本地的账户密码都清除掉localStorage.clear(),sessionStorage.clear()
开始操作
  • 需要进行下载express与md5的包
npm init -y  先下载
npm i express --save 再下载
npm install js-md5
  • md5加密
    引入在线文档
    在线引入BootCDN连接
    对字符串进行自己二次加密 比如先将字符串转换成数组然后翻转再转换成字符串加密
    注意的是md5加密是不可逆的 所有后台那边二次加密的方法要和前台保持一致
 // console.log(md5('123456'))
    function reverseStr(str) {
          //将md5加密再进行一次翻转
          return str.split('').reverse().join('')
      }

   function fmtPwd(password) {
        //嵌套两层md5加密以及翻转
        return md5(reverseStr(md5(reverseStr(password))))
    }
  • node.js中需要下载包与中间器
// 处理程序之前,在中间件中对传入的请求体进行解析(response body)
const md5 = require('js-md5')
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded())
  • 如果没有带token headers里为空的
    在这里插入图片描述
    后台返回非法请求
    在这里插入图片描述

  • 使用postman测试 即使token有值 但是是错误的则也会返回非法请求

  • 只有在登录成功后,后台返回的ase加密后的token字符串后每次请求带上令牌 才会请求成功
    后台返回的令牌存入到本地了,以后每次请求都带上令牌
    在这里插入图片描述

  • 带上令牌后请求,就能请求到啦
    在这里插入图片描述

  • 每次请求数据时都要带个令牌比较麻烦 ,我们可以通过axios进行封装一下 ,这样每次请求都会带上token

		// 每次请求都要将token放在headers里传到后台
        // 这里通过文档进行了封装
        var instance = axios.create({
            baseURL: 'http://12XX.0.0.1:8888'
        });

        let $get = function (url) {
            // 如果没有token就为空
            instance.defaults.headers.common['token'] = localStorage.getItem('token') || '';
            return instance.get(url)
        }
        let $post = function (url,data) {
            // 在实例已创建后修改默认值
            instance.defaults.headers.common['token'] = localStorage.getItem('token') || '';
            return instance.post(url,data)
        }
node.js 内容
const express = require('express')
const app = express()

// 处理程序之前,在中间件中对传入的请求体进行解析(response body)
const md5 = require('js-md5')
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded())

//解决跨域的问题:设置静态资源目录 页面直接访问这个后台地址
app.use('/', express.static('public'))

//引入aes的代码
const util = require('./utils')

/* 加密
console.log(util.encryption('123123'))
解密
console.log(util.decryption('Ly0DBA8pGNj26xnAbIG8fC0KhMEi7r1EhoPjV0RaRFY=')) */

// md5对密码进行与前台相同操作的加密
function reverseStr(str) {
    return str.split('').reverse().join('')
}
function fmtPwd(password) {
    return md5(reverseStr(md5(reverseStr(password))))
}

// * :每次请求都会先走这里,相当于是个过滤器
app.use("*", (req, res, next) => {
    //如果不是登录 则都是请求的需要走里面进行验证如果aes秘密解不开将会报错 将返回一个非法请求
    if (req.baseUrl !== '/login') {
        // 在这个req的headers里找到token
        let { token } = req.headers
        if (!token) return res.json("非法请求")
        // try里如果报错,将会走catch里 没传、token不对都会报错
        try {
            // 对token进行解密
            let str = util.decryption(token)
            let time = new Date(parseInt(str.split('|')[1])).toDateString()
            let username = str.split('|')[0]
            console.log(`${username}在${time}请求了${req.baseUrl}`)
            next()
        } catch (error) {
            res.json("非法请求2")
        }
    }
    next()
})

app.post('/login', (req, res) => {
    let { username, password } = req.body
    let str = fmtPwd("123123")
    // 验证用户名和秘密是否正确
    if (username === "admin" && password === str) {
        //将令牌发给登录过的用户
        let token = util.encryption([username, +new Date()].join('|'))
        res.json({
            token,
            isSuccess: true
        })
    } else {
        res.json({
            isSuccess: false
        })
    }
})
app.get('/list', (req, res) => {
    res.json([1, 2, 3, 4])
})
app.get('/list2', (req, res) => {
    res.json([12, 22, 32, 42])
})
app.listen(8888, () => {
    console.log("app is sunning")
})
html内容
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
//md5在线引入
<script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.js"></script
Vue.config.productionTip = false
	
       // 每次请求都要将token放在headers里传到后台
       // 这里通过文档进行了封装
       var instance = axios.create({
           baseURL: 'http://xxx.0.0.1:8888'
       });

       let $get = function (url) {
           // 在实例已创建后修改默认值
           instance.defaults.headers.common['token'] = localStorage.getItem('token') || '';
           return instance.get(url)
       }
       let $post = function (url,data) {
           // 在实例已创建后修改默认值
           instance.defaults.headers.common['token'] = localStorage.getItem('token') || '';
           return instance.post(url,data)
       }


       // console.log(md5('123456'))
       function reverseStr(str) {
           //将md5加密再进行一次翻转
           return str.split('').reverse().join('')
       }

       function fmtPwd(password) {
           //嵌套两层md5加密以及翻转
           return md5(reverseStr(md5(reverseStr(password))))
       }
       const mv = new Vue({
           el: "#app",
           data() {
               return {
                   username: '',
                   password: "",
                   list: []
               }
           },
           methods: {
               async login() {
                   let {
                       data
                   } = await $post('/login', {
                       //登录将用户名 以及md5加密后的秘密传到后台
                       username: this.username,
                       password: fmtPwd(this.password)
                   })
                   if (data.isSuccess) {
                       //登录成功后,将token 令牌保存到本地的storage里
                       alert("登录成功")
                       localStorage.setItem('token', data.token)
                   } else {
                       alert("登录失败")
                   }
               },
               // 获取数据
               async getlist() {
                   let {
                       data
                   } = await $get('/list2')
                   this.list = data
               }
           },
       })

aes加密的js代码
'use strict';
const crypto = require('crypto');

/**
 * AES加密的配置 
 * 1.密钥 
 * 2.偏移向量 
 * 3.算法模式CBC 
 * 4.补全值
 */
var AES_conf = {
    key: getSecretKey(), //密钥
    iv: '1012132405963708', //偏移向量
    padding: 'PKCS7Padding' //补全值
}

/**
 * 读取密钥key
 * 更具当前客户端的版本vid、平台platform获取对应的key
 */
function getSecretKey(){
    return "abcdabcdabcdasss";
}

/**
 * AES_128_CBC 加密 
 * 128位 
 * return base64
 */
function encryption(data) {
    let key = AES_conf.key;
    let iv = AES_conf.iv;
    // let padding = AES_conf.padding;

    var cipherChunks = [];
    var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    cipher.setAutoPadding(true);
    cipherChunks.push(cipher.update(data, 'utf8', 'base64'));
    cipherChunks.push(cipher.final('base64'));
    return cipherChunks.join('');
}


/**
 * 解密
 * return utf8
 */
function decryption(data){

    let key = AES_conf.key;
    let iv = AES_conf.iv;
    // let padding = AES_conf.padding;

    var cipherChunks = [];
    var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
    decipher.setAutoPadding(true);
    cipherChunks.push(decipher.update(data, 'base64', 'utf8'));
    cipherChunks.push(decipher.final('utf8'));
    return cipherChunks.join('');
}

module.exports= {
    encryption,decryption
}

在vue中存储storage比较麻烦可以封装
export const setSession = (key, val) => sessionStorage.setItem(key, val)
export const getSession = key => sessionStorage.getItem(key)
export const clearSession = () => sessionStorage.clear()
export const setStorage = (key, val) => localStorage.setItem(key, val)
export const getStorage = key => localStorage.getItem(key)
export const clearStorage = () => localStorage.clear()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值