如何实现基于vue技术的管理系统的用户是否登录
问题:在进行前后端分离开发时候,我们会处理一些前端用户的登录状态。如果用户没有进行登录,则不允许用户访问某些页面
一、登录方式
首先可以先了解一下前后端分离后的登录方式
(1)Cookie+Session
(2)Token
二、Cookie+Session
HTTP 是一种无状态的协议,客户端每次发送请求时,首先要和服务器端建立一个连接,在请求完成后又会断开这个连接。这种方式可以节省传输时占用的连接资源,但同时也存在一个问题:每次请求都是独立的,服务器端无法判断本次请求和上一次请求是否来自同一个用户,进而也就无法判断用户的登录状态。
为了解决 HTTP 无状态的问题,Lou Montulli 在 1994 年的时候,推出了 Cookie。
- 用户访问 a.com/pageA,并输入密码登录。
- 服务器验证密码无误后,会创建 SessionId,并将它保存起来。
- 服务器端响应这个 HTTP 请求,并通过 Set-Cookie 头信息,将 SessionId 写入 Cookie 中。
第一次登录完成之后,后续的访问就可以直接使用 Cookie 进行身份验证了
Cookie+Session存在的问题
- 由于服务器端需要对接大量的客户端,也就需要存放大量的 SessionId,这样会导致服务器压力过大。
- 如果服务器端是一个集群,为了同步登录态,需要将 SessionId 同步到每一台机器上,无形中增加了服务器端维护成本。
- 由于 SessionId 存放在 Cookie 中,所以无法避免 CSRF 攻击。
三、Token
Token 是服务端生成的一串字符串,以作为客户端请求的一个令牌。当第一次登录后,服务器会生成一个 Token 并返回给客户端,客户端后续访问时,只需带上这个 Token 即可完成身份认证
- 用户输入账号密码,并点击登录。
- 服务器端验证账号密码无误,创建 Token。
- 服务器端将 Token 返回给客户端,由客户端自由保存。
- 用户访问 a.com/pageB 时,带上第一次登录时获取的 Token。
- 服务器端验证 Token ,有效则身份验证成功。
Token的优缺点
- 服务器端不需要存放 Token,所以不会对服务器端造成压力,即使是服务器集群,也不需要增加维护成本。
- Token 可以存放在前端任何地方,可以不用保存在 Cookie 中,提升了页面的安全性。
- Token 下发之后,只要在生效时间之内,就一直有效,如果服务器端想收回此 Token 的权限,并不容易。
四、前端技术实现思路
在Vue中可以通过使用路由守卫来判断用户是否已经登录。
首先,需要创建一个全局的路由守卫函数,该函数会在每次导航之前被调用。我们可以在这个函数里面进行验证用户是否已经登录的操作
// main.js文件
import Vue from 'vue'
import App from './App.vue'
import router from './router' // 引入自定义的路由配置
const isLoggedIn = () => {
// 根据业务逻辑判断用户是否已经登录
return true; // 返回true表示已登录,false则未登录
}
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isLoggedIn()) {
// 若目标页面设置了 requiresAuth 属性且当前用户未登录,则重定向到登录页面
next('/login')
} else {
next()
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
然后,在路由配置文件(router/index.js)中为需要限制登录才能访问的组件添加 requiresAuth 元字段。
// router/index.js文件
import Vue from 'vue'
import Router from 'vue-router'
import HomePage from '@/views/HomePage.vue'
import LoginPage from '@/views/LoginPage.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: HomePage,
meta: { requiresAuth: true }, // 设置 requiresAuth 属性
},
{
path: '/login',
name: 'login',
component: LoginPage,
},
],
})
最后,在模板中就可以直接使用 <router-view> 来显示对应的页面内容了。
<!-- App.vue -->
<template>
<div id="app">
<router-view></router-view> <!-- 此处将展示不同的页面内容 -->
</div>
</template>
这样,当用户没有登录时,他们将无法访问 / 或其他需要登录才能访问的页面,而会被重定向到登录页面。
配置代理转发(vue.config.js),解决跨域问题
module.exports = {
devServer: {
// 代理配置
proxy: {
'/api': {
target: 'http://localhost:3000' // 我们要代理的真实接口地址
}
}
}
}