vue前端实现登录
Vue 前端登录实现方案
登录表单组件
创建独立的登录组件 Login.vue 包含表单元素:
<template>
<form @submit.prevent="handleSubmit">
<input v-model="form.username" type="text" placeholder="用户名"/>
<input v-model="form.password" type="password" placeholder="密码"/>
<button type="submit">登录</button>
</form>
</template>
<script>
export default {
data() {
return {
form: {
username: '',
password: ''
}
}
},
methods: {
async handleSubmit() {
try {
const res = await this.$axios.post('/api/login', this.form)
localStorage.setItem('token', res.data.token)
this.$router.push('/dashboard')
} catch (error) {
console.error('登录失败', error)
}
}
}
}
</script>
状态管理
使用 Vuex 管理登录状态:
// store/auth.js
export default {
state: {
user: null,
isAuthenticated: false
},
mutations: {
SET_USER(state, user) {
state.user = user
state.isAuthenticated = !!user
}
},
actions: {
async login({ commit }, credentials) {
const response = await axios.post('/api/login', credentials)
commit('SET_USER', response.data.user)
return response
}
}
}
路由守卫配置
在路由配置中添加导航守卫:
// router/index.js
router.beforeEach((to, from, next) => {
const isAuthenticated = store.state.auth.isAuthenticated
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login')
} else {
next()
}
})
令牌处理
实现自动令牌附加的 axios 拦截器:
// utils/http.js
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
store.dispatch('logout')
router.push('/login')
}
return Promise.reject(error)
}
)
安全增强措施
- 实现 CSRF 防护:从后端获取 CSRF 令牌并包含在请求头中
- 密码加密:使用 bcryptjs 在客户端进行初步哈希处理
- 会话超时:设置定时器检查令牌有效期
第三方登录集成
示例 GitHub OAuth 集成:
// 重定向到认证服务器
window.location.href = `https://github.com/login/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=${window.location.origin}/oauth-callback`
// 回调页面处理
const code = new URLSearchParams(window.location.search).get('code')
const { data } = await axios.post('/api/oauth/github', { code })
错误处理优化
增强表单提交的错误反馈:
<template>
<div v-if="error" class="error-message">
{{ errorMessage }}
</div>
</template>
<script>
export default {
data() {
return {
error: null
}
},
methods: {
async handleSubmit() {
this.error = null
try {
// 登录逻辑
} catch (error) {
this.error = error.response?.data?.message || '登录失败'
}
}
}
}
</script>






