下载Win64OpenSSL_Light-1_1_1c
生成公钥和私钥,在将公钥和私钥放入pem
文件夹中
将openssl的安装路径添加到系统环境变量中:C:\Program Files\OpenSSL-Win64\bin
生成私钥: openssl genrsa -out rsa_private_key.pem 1024
用私钥生成公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem可选:
对私钥进行pkcs8编码:openssl pkcs8 -in rsa_private_key.pem -topk8 -out pkcs9_rsa_private_key.pem -inform PEM -outform PEM -nocrypt
生成加密的私钥:openssl genrsa -aes256 -passout pass:123456 -out aes_rsa_private_key.pem 1024
通过加密私钥生成公钥:openssl rsa -in aes_rsa_private_key.pem -passin pass:123456 -pubout -out rsa_public_key.pem
创建jwt.js
模块,写入生成token
和验证token
的方法
/* 一、引入模块依赖 */
const fs = require(‘fs‘);
const path = require(‘path‘);
const jwt = require(‘jsonwebtoken‘);
/* 二、生成token */
function generateToken(data) {
let created = Math.floor(Date.now() / 1000); // 创建token生成的时间(s)
let cert = fs.readFileSync(path.join(__dirname, ‘./pem/rsa_private_key.pem‘)); //私钥 可以自己生成
let token = jwt.sign({
data,
exp: created + 60 * 60, // 生成后1小时失效
}, cert, { algorithm: ‘RS256‘ });
return token;
}
/* 三、校验token */
function verifyToken(token) {
let cert = fs.readFileSync(path.join(__dirname, ‘./pem/rsa_public_key.pem‘)); //公钥 可以自己生成
let res;
try {
if (token !== undefined) {
let result = jwt.verify(token, cert, { algorithms: [‘RS256‘] }) || {};
res = result.data || {};
}
} catch (e) {
res = e;
}
return res;
}
/* 导出生成和校验token的方法 */
module.exports = { generateToken, verifyToken };
在登录的路由中生成token
res.send({ code: 1, token: jwt.generateToken(result[0]) });
即利用
jwt.js
中生成token
的方法生成字符串并返回给客户端
创建中间件,拦截特定的url进行token
验证
app.use((req, res, next) => {
if (req.url != ‘/user/login‘ && (req.url.startsWith("/user") || req.url.startsWith("/orders"))) {
let token = req.headers.token;
let result = jwt.verifyToken(token);
// 如果考验通过就next,否则就返回登陆信息不正确
if (result === undefined) {
res.send({ status: 403, msg: "未提供证书" })
} else if (result.name == ‘TokenExpiredError‘) {
res.send({ status: 403, msg: ‘登录超时,请重新登录‘ });
} else if (result.name == "JsonWebTokenError") {
res.send({ status: 403, msg: ‘证书出错‘ })
} else {
req.user = result;
next();
}
} else {
next();
}
});
对axios
模块做一些初始化;客户端发送请求时,为请求加上token
字符串,并使得post可以对象的方式传递参数;客户端收到响应后,根据服务器返回的token的状态,对storage
里的token
进行增删操作,并设置vuex中的相关变量。
import axios from "axios";
import qs from "qs";
import store from ‘./store‘
const Axios = axios.create({
baseURL: "http://localhost:5050/",
withCredentials: true
})
Axios.interceptors.request.use(
config => {
// console.log("进入请求拦截器...");
//this.axios.post(
//"user/signin",
//{uname:dingding , upwd:123456}
//)
if (config.method === "post") {
config.data = qs.stringify(config.data) // post(‘/‘, {请求的参数}),将post中req对象转为字符串(即发送post请求时,可以使用对象)
}
if (localStorage.getItem("token")) {
config.headers.token = localStorage.getItem("token");
}
if (sessionStorage.getItem("token")) {
config.headers.token = sessionStorage.getItem("token");
}
return config;
},
error => {
console.log("===发送请求拦截器报错===")
console.log(error);
console.log("===end===");
Promise.reject(error);
}
);
Axios.interceptors.response.use(
res => {
// console.log("触发响应拦截器...")
if (res.data.status == 403) {
localStorage.removeItem("token");
sessionStorage.removeItem("token");
store.commit("setIslogin", false);
store.commit("setUname", "");
} else if (res.data.code == -1) {
store.commit("setIslogin", false);
store.commit("setUname", "");
//alert(res.data.msg+" 请先登录 !");
} else if (res.data.token) {
store.commit("setUname", res.data.uname);
store.commit("setIslogin", true);
if (res.remember === "true") {
localStorage.setItem("token", res.data.token);
} else {
sessionStorage.setItem("token", res.data.token);
}
}
return res;
},
error => {
}
)
export default {
install: function(Vue, Option) {
Vue.prototype.axios = Axios;
}
}
将初始化后的axios.js
模块导入main.js
中
import axios from ‘./axios‘
原文:https://www.cnblogs.com/CarlaZhou/p/14987823.html