登录一般是怎么做的
- 首先后台会给前台一个接口,前台进行测试。对密码进行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()