供求网站建设,湖州网络推广竞价,公司网站页面设计思路,山东临沂市建筑模板生产厂家目录
设置找回密码请求拦截器
1.相关参数
2.约定
代码实现
1. 实现思路
2. 实现代码 校园统一身份认证系统#xff1a;
基于网络安全#xff0c;找回密码、重新设置密码的流程和正常登录流程中密钥等请求头不一致。 设置找回密码请求拦截器
1.相关参数
clientId 应…目录
设置找回密码请求拦截器
1.相关参数
2.约定
代码实现
1. 实现思路
2. 实现代码 校园统一身份认证系统
基于网络安全找回密码、重新设置密码的流程和正常登录流程中密钥等请求头不一致。 设置找回密码请求拦截器
1.相关参数
clientId 应用ID在点击忘记密码跳转后携带如下所示 http://192.168.31.134:8080/? clientId webApp secretKey 3dtii4jr91iz8ypj secretValue ecmo5dro13as5y79 secretKey 密钥的key在点击忘记密码跳转后携带如下所示 http://192.168.31.134:8080/ ? clientId webApp secretKey 3dtii4jr91iz8ypj secretValue ecmo5dro13as5y79 secretValue 密钥的value在点击忘记密码跳转后携带如下所示 http://192.168.31.134:8080/ ? clientId webApp secretKey 3dtii4jr91iz8ypj secretValue ecmo5dro13as5y79 nonce 随机字符串10分钟内不要重复 timestamp 时间戳毫秒纯数字 sign 签名利用上面的参数使用SM3加密算法生成的加密字符串加密前的明文如下所示加密时没有用到secretKey nonce { 随机字符串 } ×tamp { 时间戳 ( 毫秒 )} clientId { 应用 ID} secret {secretValue} jwtSecret 生成jwt的密钥值是 8w9L95DwBCD9xjkR 2.约定 从统一登录页点击忘记密码跳转时会携带 1 个参数如下所示 http://192.168.31.134:8080/AccountBack ? key eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6IndlYkFwcCIsInNlY3JldEt leSI6ImF2dGxuYXlldnBtbWo5NDgiLCJzZWNyZXRWYWx1ZSI6InMzZ2Jma2QzdDI2YWJ5NzQifQ.y1eT agvFM8gPxC1k2oqZIwr_9-IhyHAhWJqkZ8CFrnI 将 clientId 、 secretKey 、 secretValue 、 timeEnd 作为参数以 jwtSecret 为密钥生成的结果 就是 key 其中 timeEnd 是 key 有效截止时间的时间戳。 每次请求 前都需要判断 key 是否还有效如果无效需要重新开始忘记密码的流程。 每次请求 都需要以 clientId timestamp , nonce , secretKey , sign 这 5 个值为参数以 jwtSecret 为密钥生成 key 并将结果放入请求头的 key 参数中。 【 注 】 : 1. 生成 key 时需要的是 secretKey 而不是 secretValue。 代码实现 1. 实现思路 jwtDecode对key解码。获取数据secretKey密钥secretValue密钥值timeEnd有效截至时间redirectUri退回登录时需要携带url的标识。获取当前时间戳检查是否超过有效截至时间。生成签名sign、随机字符串nonce无长度字符限制为避免出错现在在数字和字母中符号在解析过程中容易出错jwt加密重新生成新的key。 2. 实现代码 使用router 文件 index.js 中的 accessToken const router new VueRouter({mode: history,base: process.env.BASE_URL,routes,
});
const VueRouterPush VueRouter.prototype.push;
VueRouter.prototype.push function push(to) {return VueRouterPush.call(this, to).catch((err) err);
};router.beforeEach((to, from, next) {const fullPathto.fullPath.match(/\?(.*)/)if(fullPath) {const searchParams new URLSearchParams(fullPath[1])if (searchParams.get(key)) {localStorage.setItem(accessToken, searchParams.get(key)) next(to.path)}
}else {next()
}})
export default router; request1.js和其他request.js不同中 引入文件依赖 //创建axios实例
import axios from axios;
// 导入 sm-crypto 库
import sm from sm-crypto;
import CryptoJS from crypto-js
import { jwtDecode } from jwt-decode;
import { getToken, setToken, removeToken } from /utils/auth;
import { Notification, MessageBox, Message, Loading } from element-ui;
import errorCode from /utils/errorCode;
import { eventBus } from ../../src/main; 请求拦截器 // 请求拦截器
service.interceptors.request.use((config) {// 在发送请求之前做些什么let accessToken localStorage.getItem(accessToken);// console.log(key, accessToken);//解码密钥const jwtSecret 8w9L95DwBCD9xjkR; // 生成JWT密钥,固定数值// 解码JWT令牌获取参数// clientId secretKey secretValue timeEndconst decodedToken jwtDecode(accessToken, jwtSecret);console.log(decodedToken);const clientId decodedToken.clientId; //应用IDconsole.log(clientId);console.log(clientId);const secretKey decodedToken.secretKey; //密钥const secretValue decodedToken.secretValue; //密钥值const timeEnd decodedToken.timeEnd; //获取key有效截止时间的时间戳const redirectUri decodedToken.redirectUri ? decodedToken.redirectUri : null;window.redirectUri redirectUri;window.clientId clientId; // 存储在全局变量中// 通过事件总线发送事件通知eventBus.$emit(dataUpdated, {clientId,redirectUri});console.log(window.clientId);console.log(window.clientId);// 检查key是否有效if (timeEnd Date.now() Number(timeEnd)) {// key已过期重新开始忘记密码流程return Promise.reject(); //超时请求中断}const nonce generateNonce(); // 生成随机字符串nonceconst timestamp Date.now(); // 获取当前时间戳毫秒级别const sign generateSign(nonce, timestamp, clientId, secretValue); // 生成签名sign// 生成加密keyconst payload {clientId,timestamp,nonce,secretKey,sign,};const jwtToken generateKey(payload, jwtSecret);// console.log(key);// console.log(jwtToken);config.headers[key] jwtToken; // 将key添加到请求头中并转换为字符串类型 // 将key添加到请求头中并转换为字符串类型return config;},(error) {// 对请求错误做些什么return Promise.reject(error);}
);
// 生成随机字符串nonce的函数
function generateNonce() {const characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789;const length 16;let nonce ;for (let i 0; i length; i) {nonce characters.charAt(Math.floor(Math.random() * characters.length));}return nonce;
}// 生成签名sign的函数
function generateSign(nonce, timestamp, clientId, secretValue) {const plaintext nonce${nonce}timestamp${timestamp}clientId${clientId}secret${secretValue};const sign sm.sm3(plaintext); // 使用sm-crypto库中的sm3函数生成签名return sign;
}// 函数用于将对象编码为Base64格式
function encodeBase64(obj) {const stringifiedObj JSON.stringify(obj);const wordArray CryptoJS.enc.Utf8.parse(stringifiedObj);return CryptoJS.enc.Base64.stringify(wordArray).replace(/$/, );
}// 生成JWT的函数
function generateJWT(payload, secret) {// 定义JWT的头部const header { alg: HS256, typ: JWT };// 编码头部和负载const encodedHeader encodeBase64(header);const encodedPayload encodeBase64(payload);// 生成签名const signature CryptoJS.HmacSHA256(encodedHeader . encodedPayload,secret);const signatureBase64 CryptoJS.enc.Base64.stringify(signature).replace(/$/,);const jwtToken ${encodedHeader}.${encodedPayload}.${signatureBase64};return jwtToken;
}
// 生成key的函数
function generateKey(payload, jwtSecret) {const jwtToken generateJWT(payload, jwtSecret);return jwtToken;
} 响应拦截器无特殊处理 function logOutWay() {MessageBox.confirm(未登录或登录已过期请重新登录。, 系统提示, {confirmButtonText: 重新登录,showCancelButton: false,distinguishCancelAndClose: false,showClose: false,closeOnClickModal: false,type: warning}).then(() {// 跳转到登录页面let accessTokenKey getToken()removeToken()localStorage.removeItem(accessToken)window.location.href process.env.VUE_APP_BASE_JUMPauth/logout?accessToken accessTokenKey redirectUriprocess.env.VUE_APP_BASE_JUMP}).catch(() {});}// 响应拦截器
service.interceptors.response.use((res) {const isEncrypt true;if (isEncrypt true !matchs(res.config.url, excludPtahs)) {//console.log(解密)res.data JSON.parse(interfaceDecryptSm2(res.data));}// console.log(拦截器, res);// 未设置状态码则默认成功状态const code res.data.code || 0;// 获取错误信息const msg errorCode[code] || res.data.msg || errorCode[default];// 二进制数据则直接返回if (res.request.responseType blob ||res.request.responseType arraybuffer) {// console.log(1111);return res.data;}if (code 401) {} else if (code 1) {if (msg msg.includes(key不存在或已过期)) {logOutWay()// 中断请求return Promise.reject(无效的会话或者会话已过期请重新登录。);} else {Message({ message: msg, type: error });return Promise.reject(new Error(msg));}} else if (code 601) {Message({ message: msg, type: warning });return Promise.reject(error);}// else if (code ! 0) {// Notification.error({ title: msg })// return Promise.reject(error)// }else {// console.log(22222,res.data);return res.data;}},(error) {console.log(err error);let { message } error;if (message Network Error) {message 后端接口连接异常;} else if (message.includes(timeout)) {message 系统接口请求超时;} else if (message.includes(Request failed with status code)) {if (message.substr(message.length - 3) 401) {console.log(401走重新请求token逻辑);message 未登录或登录已过期请重新登录。;} else {message 系统接口 message.substr(message.length - 3) 异常;}}Message({ message: message, type: error, duration: 5 * 1000 });return Promise.reject(error);}
);//导入文件
export default service;