以下是使用Session/Cookie在Vue前端和Django后端实现用户认证的详细步骤:

1. Django 后端配置

安装依赖

确保你已经安装了Django和Django REST Framework:

pip install django
pip install djangorestframework

配置 Django 设置

settings.py 中添加必要的配置:

# settings.py
 
INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',  # 使用Django自带的token认证
    'corsheaders',  # 允许跨域请求
]
 
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',  # 允许跨域请求
    'django.middleware.common.CommonMiddleware',
]
 
CORS_ALLOWED_ORIGINS = [
    'http://localhost:8080',  # Vue前端的地址
]
 
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}
 
# 确保使用Django自带的会话和认证系统

配置登录视图

创建一个用于处理登录请求的视图:

# views.py
 
from django.contrib.auth import authenticate, login
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
 
@csrf_exempt
def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return JsonResponse({'message': 'Login successful'})
        else:
            return JsonResponse({'message': 'Invalid credentials'}, status=401)
    return JsonResponse({'message': 'Only POST method is allowed'}, status=400)

配置URL

urls.py 中添加登录视图的URL:

# urls.py
 
from django.urls import path
from .views import login_view
 
urlpatterns = [
    path('login/', login_view, name='login'),
    # 其他URL配置
]

2. Vue 前端配置

安装 Axios

npm install axios

配置 Axios

src 目录中创建一个 auth.js 文件,用于管理登录状态和会话:

// src/auth.js
 
import axios from 'axios';
import router from './router';
 
const apiClient = axios.create({
    baseURL: 'http://localhost:8000',  // Django后端地址
    withCredentials: true,  // 允许跨域请求携带cookie
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
});
 
export default apiClient;

创建登录组件

src/components 目录中创建 Login.vue

<template>
  <div>
    <h1>Login</h1>
    <form @submit.prevent="login">
      <div>
        <label for="username">Username:</label>
        <input type="text" v-model="username" required />
      </div>
      <div>
        <label for="password">Password:</label>
        <input type="password" v-model="password" required />
      </div>
      <button type="submit">Login</button>
    </form>
  </div>
</template>
 
<script>
import apiClient from '../auth';
 
export default {
  data() {
    return {
      username: '',
      password: '',
    };
  },
  methods: {
    async login() {
      try {
        const response = await apiClient.post('/login/', {
          username: this.username,
          password: this.password,
        });
        alert(response.data.message);
        if (response.data.message === 'Login successful') {
          this.$router.push('/');
        }
      } catch (error) {
        console.error('An error occurred:', error);
        alert('Invalid credentials');
      }
    },
  },
};
</script>

3. 保护路由

src/router/index.js 中设置路由守卫:

import Vue from 'vue';
import Router from 'vue-router';
import Home from '../views/Home.vue';
import Login from '../views/Login.vue';
import apiClient from '../auth';
 
Vue.use(Router);
 
const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      meta: { requiresAuth: true },
    },
    {
      path: '/login',
      name: 'Login',
      component: Login,
    },
  ],
});
 
router.beforeEach(async (to, from, next) => {
  const loggedIn = await apiClient.get('/authenticated/')
    .then(response => response.data.authenticated)
    .catch(() => false);
 
  if (to.matched.some(record => record.meta.requiresAuth) && !loggedIn) {
    next('/login');
  } else {
    next();
  }
});
 
export default router;

4. 确认用户登录状态

在 Django 中创建一个用于检查用户是否已登录的视图:

# views.py
 
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
 
@login_required
def authenticated_view(request):
    return JsonResponse({'authenticated': True})
 
urlpatterns += [
    path('authenticated/', authenticated_view, name='authenticated'),
]

在 Vue 组件中,可以通过调用该接口来确认用户是否已登录。例如,在 Home.vue 中:

<template>
  <div>
    <h1>Home</h1>
    <p>Welcome to the home page!</p>
  </div>
</template>
 
<script>
import apiClient from '../auth';
 
export default {
  async created() {
    const response = await apiClient.get('/authenticated/');
    if (!response.data.authenticated) {
      this.$router.push('/login');
    }
  },
};
</script>

通过以上步骤,你可以使用Session/Cookie在Vue前端和Django后端实现用户认证。这样配置后,每次请求时浏览器会自动携带Cookie,后端可以通过Session确认用户身份,确保用户登录状态的安全和可靠。