服务器配置jwt
-
安装
jwt
库 :npm i jsonwebtoken
-
导入
jwt
库,并声明传输密钥 -
实现颁发
jwt
功能,即往header
里面加入authorization
字段/** * 颁发jwt * @param {*} res 服务端向客户端发送的响应 * @param {*} info 主体信息 * @param {*} maxAge 过期时间 */ exports.publish = function (res, maxAge = 3600 * 24, info = {}) { const token = jwt.sign(info, secrete, { expiresIn: maxAge, }); // 往header里面添加authorization字段 res.header("authorization", token); };
-
在
login
接口下响应,如果登录成功就颁发jwt
,第三个参数info
传入登录成功的用户id
-
实现验证
jwt
功能,判断当前是否存在token
,或者已存在的token
是否有效// 认证jwt exports.verify = function (req) { let token; // 从headers获取token token = req.headers["authorization"]; if (!token) { // 如果header中还是没有token,那验证失败 return null; } // 严格规定下,token会有以下格式 bearer xxxxxxx,所以需要做截断 token = token.split(" "); token = token.length == 1 ? token[0] : token[1]; try { const result = jwt.verify(token, secrete); return result; } catch { return null; } };
-
在
token中间件
中利用jwt
验证请求- 如果验证的结果返回有值(不为
null
),则在请求头中加上返回的管理员信息的id - 如果认证失败(返回结果为
null
),则返回403错误
- 如果验证的结果返回有值(不为
开发客户端
-
jwt
,登陆成功以后往响应头返回authorization
字段,值为对应的token
-
在根目录下创建
vue.config.js
,配置代理下的开发服务器。当访问"/api"
地址时,跳转到服务器所在地址"http://localhost:5009"
devServer: { proxy: { "/api": { target: "http://localhost:5009", }, }, }
-
通过
axios
发送网络请求
用axios.create
创建实例,对实例进行重新封装,最后返回实例- 发送请求的时候,如果已经有
token
了,就在实例的响应头里返回
通过axios实例.interceptors.response.use
拦截器来对响应结果/错误结果进行处理
const token = localStorage.getItem("token"); let instance = axios; if(token){ // 1.如果token有值,在响应头里加上 instance = axios.create({ // 创建axios实例 headers: { authorization: "bearer " + token } }) }
-
响应的时候,如果有
token
,就保存到localstorage
-
如果响应状态码是
403
,表示token
无效或过期,那么就删除localstorage
里面的token
// 拦截器处理响应 instance.interceptors.response.use((resp)=>{ // 2. 响应的时候,如果有token,就保存到localstorage if(resp.headers.authorization) { localStorage.setItem("token", resp.headers.authorization); } return resp; }, (err)=>{ // 3. 如果响应状态码为403(token过期或无效),删除token if(err.response.status == 403) { localStorage.removeItem("token"); } return Promise.reject(err); });
- 发送请求的时候,如果已经有
-
开发请求接口,向服务器发送网络请求(
axios
)在登录服务
loginService
里导入重新封装过的axios
,通过这个新封装的对象的post、get
请求来实现登录、注销和查看当前用户功能export async function login(loginId, loginPwd) { await delay(1000); const resp = await request().post("/api/admin/login", { loginId, loginPwd }); return resp.data; } // request()返回的结果是重新封装过的axios实例
-
开发仓库,用单独文件写
loginUser
模块 -
在
main.js
最开始,dispatch
一次loginUser模块
里的whoAmI
,来判断当前是否已经有用户登录了store.dispatch("loginUser/whoAmI"); // 网站被访问的时候就看看当前是谁在登录
-
有些页面是需要登陆之后才能进入的,
要在对应页面的路由里添加导航守卫进行鉴权,通过beforeEnter
设置这些页面在进入之前就要判断
判断仓库里面的store.state.loginUser.data
是否有值,有值就表示已登录,可以next()
继续访问
如果没有就返回到登录页面next("/login")
{ path: "/user", component: () => import("../views/User.vue"), beforeEnter(to, from, next) { if(store.state.loginUser.data) { // 有用户 next(); } else { next("/login"); } }, },
-
登录页面点击登录按钮,
dispatch
触发仓库里面的登录事件,把文本框里的账号密码作为参数传入
登陆成功后跳转到个人中心页面 -
点击注销按钮以后
1.dispatch
触发登出功能
2.自动跳转回登录页面this.$router.push("/login")
-
客户端开发完成,进行打包,在
vue.config.js
里面添加outputDir
打包到服务器的public目录
下outputDir: path.resolve(__dirname, "../public")
-
npm run build
打包 -
打包完成以后就可以直接通过服务器的地址访问静态资源页面
-
刷新重新请求,会请求一个打包完成后没有的静态资源(比如5009/user),
用api history fallback
工具,如果刷新重新请求请求不到的话,就返回index.html
安装工具:npm i connect-history-api-fallback