登录密码加密

首先  在api文件夹里封装axios

1、安装包

crypto-js    jsencrypt

2、在utils下创建一个 .js文件夹  将加密封装

/*
 * @Descripttion: 工具集
 * @version: 1.2
 * @LastEditors: sakuya
 * @LastEditTime: 2022年5月24日00:28:56
 */
// 安装引包
import CryptoJS from 'crypto-js';
import JSEncrypt from 'jsencrypt';

const tool = {}

/* 复制对象 */
tool.objCopy = function (obj) {
	return JSON.parse(JSON.stringify(obj));
}

/* 日期格式化 */
tool.dateFormat = function (date, fmt = 'yyyy-MM-dd hh:mm:ss') {
	date = new Date(date)
	var o = {
		"M+": date.getMonth() + 1,                 //月份
		"d+": date.getDate(),                    //日
		"h+": date.getHours(),                   //小时
		"m+": date.getMinutes(),                 //分
		"s+": date.getSeconds(),                 //秒
		"q+": Math.floor((date.getMonth() + 3) / 3), //季度
		"S": date.getMilliseconds()             //毫秒
	};
	if (/(y+)/.test(fmt)) {
		fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
	}
	for (var k in o) {
		if (new RegExp("(" + k + ")").test(fmt)) {
			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
		}
	}
	return fmt;
}

/* 千分符 */
tool.groupSeparator = function (num) {
	num = num + '';
	if (!num.includes('.')) {
		num += '.'
	}
	return num.replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
		return $1 + ',';
	}).replace(/\.$/, '');
}

/* 常用加解密 */
tool.crypto = {
	//MD5加密
	MD5(data) {
		return CryptoJS.MD5(data).toString()
	},
	//BASE64加解密
	BASE64: {
		encrypt(data) {
			return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data))
		},
		decrypt(cipher) {
			return CryptoJS.enc.Base64.parse(cipher).toString(CryptoJS.enc.Utf8)
		}
	},
	//AES加解密
	AES: {
		encrypt(data, secretKey, config = {}) {
			if (secretKey.length % 8 != 0) {
				console.warn("[SCUI error]: 秘钥长度需为8的倍数,否则解密将会失败。")
			}
			const result = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(secretKey), {
				iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
				mode: CryptoJS.mode[config.mode || "ECB"],
				padding: CryptoJS.pad[config.padding || "Pkcs7"]
			})
			return result.toString()
		},
		decrypt(cipher, secretKey, config = {}) {
			const result = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Utf8.parse(secretKey), {
				iv: CryptoJS.enc.Utf8.parse(config.iv || ""),
				mode: CryptoJS.mode[config.mode || "ECB"],
				padding: CryptoJS.pad[config.padding || "Pkcs7"]
			})
			return CryptoJS.enc.Utf8.stringify(result);
		}
	},
	//RSA公钥加密
	RSA: {
		encrypt(data, publicKey) {
			if (!publicKey) {
				console.warn("未设置publicKey,加密将会失败。");
			}
			var encrypt = new JSEncrypt();
			encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + publicKey + '-----END PUBLIC KEY-----');
			return encrypt.encrypt(data.toString());
		}
	}
}

/* JWT */
tool.jwt = {
	decrypt(token) {
		token = token.replace(/_/g, "/").replace(/-/g, "+");
		var json = decodeURIComponent(escape(window.atob(token.split(".")[1])));
		return JSON.parse(json);
	},
	getDate(timestamp) {
		return new Date(timestamp * 1000);
	}
}

tool.helper = {
	//去掉Html标签
	removeHtml(value) {
		return value.replace(/<[^>]+>/g, '');
	},
	removeHtmlSub(value) {
		var str = value.replace(/<[^>]+>/g, '');
		if (str.length > 50) return str.substring(0, 50) + '......';
		else return str;
	}
}

/* 文件 */
tool.file = {
	/**
	 * 下载在线图片
	 * @param {*} url 
	 * @param {*} fileName 
	 * @param {*} mime 
	 * @param {*} bom 
	 */
	downloadByByOnlineUrl(url,fileName,mime,bom){
		tool.file.urlToBase64(url).then((base64) => {
			tool.file.downloadByBase64(base64, fileName, mime, bom);
		});
	},
	/**
	 * 根据Base64下载 图片
	 * @param {*} buf 
	 * @param {*} fileName 
	 * @param {*} mime 
	 * @param {*} bom 
	 */
	downloadByBase64(buf,fileName,mime,bom){
		const base64Buf = tool.file.dataURLtoBlob(buf);
		tool.file.downloadByData(base64Buf, fileName, mime, bom);
	},
	/**
	 * 根据后台接口文件流下载
	 * @param {*} data 
	 * @param {*} fileName 
	 * @param {*} mime 
	 * @param {*} bom 
	 */
	downloadByData(data,fileName,mime,bom){
		const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
		const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
	
		const blobURL = window.URL.createObjectURL(blob);
		const tempLink = document.createElement('a');
		tempLink.style.display = 'none';
		tempLink.href = blobURL;
		tempLink.setAttribute('download', fileName);
		if (typeof tempLink.download === 'undefined') {
			tempLink.setAttribute('target', '_blank');
		}
		document.body.appendChild(tempLink);
		tempLink.click();
		document.body.removeChild(tempLink);
		window.URL.revokeObjectURL(blobURL);
	},
	/**
	 * 根据文件地址下载文件
	 * @param {*} param0 
	 * @returns 
	 */
	downloadByUrl({ url, target = '_blank', fileName }){
		const isChrome = window.navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
		const isSafari = window.navigator.userAgent.toLowerCase().indexOf('safari') > -1;
	
		if (/(iP)/g.test(window.navigator.userAgent)) {
			console.error('Your browser does not support download!');
			return false;
		}
		if (isChrome || isSafari) {
			const link = document.createElement('a');
			link.href = url;
			link.target = target;
	
			if (link.download !== undefined) {
				link.download = fileName || url.substring(url.lastIndexOf('/') + 1, url.length);
			}
	
			if (document.createEvent) {
				const e = document.createEvent('MouseEvents');
				e.initEvent('click', true, true);
				link.dispatchEvent(e);
				return true;
			}
		}
		if (url.indexOf('?') === -1) {
			url += '?download';
		}
	
		tool.file.openWindow(url, { target });
		return true;
	},
	openWindow(url,opt){
		const { target = '__blank', noopener = true, noreferrer = true } = opt || {};
		const feature = [];
	
		noopener && feature.push('noopener=yes');
		noreferrer && feature.push('noreferrer=yes');
	
		window.open(url, target, feature.join(','));
	},
	getFileName(headers){
		var fileName = headers['content-disposition'].split(';')[1].split('filename=')[1];
		var fileNameUnicode = headers['content-disposition'].split('filename*=')[1];
		if (fileNameUnicode) {
			//当存在 filename* 时,取filename* 并进行解码(为了解决中文乱码问题)
			fileName = decodeURIComponent(fileNameUnicode.split("''")[1]);
		}
		return fileName;
	},
	/**
	 * base64 to blob
	 * @param {*} base64Buf 
	 * @returns 
	 */
	dataURLtoBlob(base64Buf){
		const arr = base64Buf.split(',');
		const typeItem = arr[0];
		const mime = typeItem.match(/:(.*?);/)[1];
		const bstr = window.atob(arr[1]);
		let n = bstr.length;
		const u8arr = new Uint8Array(n);
		while (n--) {
			u8arr[n] = bstr.charCodeAt(n);
		}
		return new Blob([u8arr], { type: mime });
	},
	/**
	 * img url to base64
	 * @param {*} url 
	 * @param {*} mimeType 
	 * @returns 
	 */
	urlToBase64(url,mimeType){
		return new Promise((resolve, reject) => {
			let canvas = document.createElement('CANVAS');
			const ctx = canvas.getContext('2d');
	
			const img = new Image();
			img.crossOrigin = '';
			img.onload = function () {
				if (!canvas || !ctx) {
					return reject();
				}
				canvas.height = img.height;
				canvas.width = img.width;
				ctx.drawImage(img, 0, 0);
				const dataURL = canvas.toDataURL(mimeType || 'image/png');
				canvas = null;
				resolve(dataURL);
			};
			img.src = url;
		});
	},
	/**
	 * File 转 base64
	 * @param {*} file 
	 * @returns 
	 */
	fileToBase64(file){
		return new Promise((resolve, reject) => {
			const reader = new FileReader();
			reader.readAsDataURL(file);
			reader.onload = () => resolve(reader.result);
			reader.onerror = (error) => reject(error);
		});
	},
	/**
	 * Base64 转 File
	 * @param {*} dataURL 
	 * @param {*} fileName 
	 * @param {*} mimeType [可选]文件类型,默认为base64中的类型
	 * @returns 
	 */
	base64ToFile(dataURL,fileName,mimeType=null){
		var arr = dataURL.split(',');
		var defaultMimeType = arr[0].match(/:(.*?);/)[1];
		var bStr = atob(arr[1]);
		let n = bStr.length;
		var u8arr = new Uint8Array(n);
		while (n--) {
			u8arr[n] = bStr.charCodeAt(n);
		}
		return new File([u8arr], fileName, { type: mimeType || defaultMimeType });
	},
	/**
	 * Blob 转 File
	 * @param {*} blob 
	 * @param {*} fileName 文件名
	 * @param {*} mimeType 文件类型
	 * @returns 
	 */
	blobToFile(blob,fileName,mimeType){
		return new File([blob], fileName, { type: mimeType });
	}
}

export default tool

   3、在登录页 引入 封装好的文件

import tool from "@/utils/tool.js";
<template>
  <div class="header">
    <!-- 登录 -->
    <header>
      <section class="center">
        <div class="hear-left">
          <img
            src="https://yun-campus-res.oss-cn-shenzhen.aliyuncs.com/kzp/vip/login-home/hr_pc_logo.png"
            alt=""
          />
        </div>
        <div class="head-right">
          <button class="hear-btn">微信人工客服</button>
          <button class="hear-btn">操作指南</button>
        </div>
      </section>
    </header>
    <div class="max-box">
      <!-- 左边 -->
      <div class="left">
        <p class="left-p">
          <img
            src="https://yun-campus-res.oss-cn-shenzhen.aliyuncs.com/kzp/vip/login-home/fonts.png?v=1"
            alt=""
          />
          <span>部分合作高校</span>
        </p>
        <div class="left-box">
          <img
            src="https://o.bysjy.com.cn/kzp/vip/login-home/logos-1.png"
            alt=""
          />
        </div>
      </div>
      <!-- 右边 -->
      <div class="right">
        <div class="switch">
          <el-button>微信扫码登录</el-button>
          <div class="switch-twoCode">
            <img
              src="https://yun-campus-res.oss-cn-shenzhen.aliyuncs.com/kzp/vip/login-home/qr-code.png"
              alt=""
            />
          </div>
        </div>
        <el-form class="form-box" ref="loginFrom" :model="form" :rules="rules">
          <el-input
            v-model="form.phone"
            placeholder="请输入账户"
            type="text"
            @blur="check"
            ref="username"
          />
          <el-input
            v-model="form.password"
            type="password"
            placeholder="请输入密码"
            ref="userpwd"
            @blur="checkPwd"
          >
            <template #append>
              <el-button @click="forget">忘记密码 </el-button>
            </template>
          </el-input>

          <div class="inp-yzm">
            <el-input
              v-model="form.code"
              placeholder="请输入验证码"
              class="el-input_inner"
            >
            </el-input>
            <img class="yzm" :src="urls.imgs" alt="" title="点击刷新验证码" />
          </div>
          <p>
            <el-checkbox
              v-model="checked1"
              :checked="state.isOk"
              label="同意云校招"
              size="large"
            />
            <a
              href="https://hr.bysjy.com.cn/login_v2/word?guid=48FB7AC2-F562-D593-BBDE-5797D4556E30"
              target="_blank"
              >《用户协议》
            </a>
            <a
              href="https://hr.bysjy.com.cn/login_v2/word?guid=C338A93C-6E71-4601-18EA-9F126A95A538"
              target="_blank"
              >《隐私协议》</a
            >
          </p>
          <!-- 登录 -->
          <el-button
            class="btn-Login"
            size="large"
            type="primary"
            @click="loginCheck"
            :loading="islogin"
            >登录</el-button
          >
          <div class="register">
            <span class="register-left"> <a href="#">验证码登录</a> </span>
            <span class="register-right"
              >没有账号
              <span class="reg-zc" @click="toregister">立即注册></span>
            </span>
          </div>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref } from "vue";
import { ElMessageBox } from "element-plus";
import { useRouter } from "vue-router";
// 引入接口
import { loginAdminApi, getCaptchaApi, RSAKeyApi, PhoneApi } from "@/api/index";
// 加密
import tool from "@/utils/tool.js";

const router = useRouter();
const form = ref({
  phone: "",
  password: "",
  codeId: "",
  code: "",
});

const urls = reactive({
  imgs: "",
  islogin: false,
});

const state = reactive({
  isOk: false,
  publicKey: "",
});

onMounted(async () => {
  await getKey();
  // 验证码
  getCaptchaApi().then((res) => {
    // console.log("res", res);
    urls.imgs = "data:text/html;base64," + res.result?.img;
    form.value.codeId = res.result.id;
  });
});

const getKey = async () => {
  var res = await RSAKeyApi();
  state.publicKey = res.result;
};

// 手机号
const validateUserPhone = (rule, value, callback) => {
  const reg = /^[1][3-9][0-9]{9}$/;
  if (
    (!validateUserPhone && value == "") ||
    value == undefined ||
    value == null
  ) {
    callback();
    return;
  } else {
    if (!reg.test(value) && value != "") {
      callback(new Error("请按照格式输入正确的手机号码!"));
    } else {
      callback();
    }
  }
  // 检查用户名是否存在
  PhoneApi(form)
    .then((response) => {
      if (response.data.success) {
        callback(new Error("当前账号已存在,请重新输入!"));
      } else {
        callback();
      }
    })
    .catch(() => {
      callback(new Error("异步校验出错!"));
    });
};

// 密码
const validatePassword = (rule, value, callback) => {
  if (value !== "") {
    if (value.length < 8) {
      callback(new Error("请输入至少8位的密码"));
      return false;
    } else if (
      !/^(?=.*[A-Za-z])(?=.*\d)(?=.*[@!*#$%&_=])[A-Za-z\d@!*#$%&_=]{8,18}$/.test(
        value
      )
    ) {
      callback(new Error("密码必须包含字母、数字和特殊字符(@!*#$%&_=)"));
      return false;
    } else {
      callback();
    }
  }
};
const rules = reactive({
  ruleValidate: {
    phone: [
      { required: true, message: "手机号不能为空!", trugger: "blur" },
      { validator: validateUserPhone, trugger: "blur" },
    ],
    password: [
      { required: true, message: "请输入密码!", trugger: "blur" },
      { validator: validatePassword, trugger: "blur" },
    ],
  },
});
//登录
const loginCheck = async () => {
  var params = Object.assign({}, form.value);
  params.password = tool.crypto.RSA.encrypt(params.password, state.publicKey);
  loginAdminApi(params).then((res) => {
    console.log("res", res);
    if (state.isOk === true) {
      //登录成功
      //保存用户的信心(用户名、token)
      sessionStorage.setItem("username", form.value.phone);
      sessionStorage.setItem("token", res.data.data.token);
      sessionStorage.setItem(
        "checkedKeys",
        JSON.stringify(res.data.data.checkedkeys)
      );


      //获取当前登录人信息并缓存
      getHrInfoApi().then((res1) => {
        if (res1.code == 200) {
          sessionStorage.setItem("userInfo", JSON.stringify(res1.result));
        }
      })



      ElMessageBox({
        title: "提示",
        message: "登录成功!",
      });

      //跳转到主页
      router.push("/home");
    }
  });
};

// 点击立即注册
let toregister = () => {
  router.push("/register");
};
</script>

<style scoped>

</style>

4、在请求头携带token

在util下新建serve.js文件

//请求拦截器
service.interceptors.request.use((config => {
    //处理token
    //携带token
   
      // 获取token 
      let token = sessionStorage.getItem("accessToken");
      // 判断是否存在 然后发送token  // if (token) {
        if (token) {
           config.headers.Authorization ='Bearer '+ token
        }

        return config; 
    }

   
), () => {

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值