VUE django 跨域、csrf令牌的问题
作者:贪玩的小金魚
在Vue和Django进行前后分离开发时,经常会遇到跨域和CSRF令牌验证问题,本文详细介绍了如何在Django后端设置视图获取CSRF令牌,并在Vue前端进行配置以确保安全的数据交互,文章提供了后端视图创建、settings配置以及前端axios请求封装的具体方法
跨域问题
使用VUE django前后分离,跨域跟django CSRF令牌是个很头疼问题,跨域问题解决方法很多,bing一下就有很多这里先略过,主要讲一下令牌用法,取消令牌检测这里有提到django开发。
django前后分离 CSRF获取及使用
首先要获取CSRF令牌,django中GET请求是不会进行CSRF验证的,这里我们可以创建一个django视图,前端通过GET请求来获取,
Django 配置
1、获取token的视图
这里我写了两个:
- 第一个是前端发送GET请求直接获取
- 第二个是为了服务端处理登录请求时候 通过后将token以及登录所需的信息一并传递给前端
为什么想了两个,是因为懒,如果都用第一种,后端需要处理一下json数据,就直接复制只传递token字符串,在封装成json给前端。
def get_csrf_token(request): csrf_token = get_token(request) print(csrf_token) return JsonResponse({'csrfToken': csrf_token}) # return csrf_token def get_csrf_token1(request): csrf_token = get_token(request) print(csrf_token) return csrf_token
2、后端settings配置文件,需要配置以下信息。
CORS_ALLOW_HEADERS = [ 'XMLHttpRequest', 'X_FILENAME', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', 'Pragma', # 添加其他你需要的请求头,这里比较多 ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', #放到前边 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', #还有这个 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'sbh_bly_api.middleware.CustomExceptionMiddleware', ] # 配置CSRF的信任域,与跨域配置相同,这个很重要,我就是因为这个卡了一天 CSRF_TRUSTED_ORIGINS = [ 'http://127.0.0.1:8080', # 确保与前端地址匹配 ]
3、VUE前端配置
注意我的VUE项目用的ts,如果用js的请自行转换一下。
1) axios封装,这里对axios请求做了封装 http.ts文件,这里的代码,是将token存储到了 store中,这里是取值“const token = store.state.token” 根据实际项目,和习惯来确定存储位置。
// http.ts import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import store from '@/store'; // 创建 Axios 实例 const instance: AxiosInstance = axios.create({ baseURL: 'http://127.0.0.1:8000', headers: { 'Content-Type': 'application/json' }, }); // 请求拦截器 import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import store from '@/store'; // 创建 Axios 实例 const instance = axios.create({ baseURL: 'http://127.0.0.1:8000', timeout: 3000, headers: { 'Content-Type': 'application/json' }, }); // 请求相关处理 请求拦截 在请求拦截中可以补充请求相关的配置 // interceptors axios的拦截器对象 instance.interceptors.request.use(config => { // config 请求的所有信息 // console.log(config); const token = localStorage.token config.headers['X-CSRFToken'] = token return config // 将配置完成的config对象返回出去 如果不返回 请求讲不会进行 }, err => { // 请求发生错误时的相关处理 抛出错误 Promise.reject(err) }) instance.interceptors.response.use(res => { // 我们一般在这里处理,请求成功后的错误状态码 例如状态码是500,404,403 // res 是所有相应的信息 console.log(res) return Promise.resolve(res) }, err => { // 服务器响应发生错误时的处理 Promise.reject(err) }) export default instance;
2)main.ts配置项,在main中配置开启 axios 请求时发送请求头
import axios from 'axios'; axios.defaults.withCredentials = true;
3)get 请求获取令牌
import axios from '@/http' const get_token = () => { console.log("aa") var post_data = JSON.stringify({ username: "123", password: "1234" }) axios({ method: 'GET', url: axios.defaults.baseURL + '/api/get-csrf-token/', data: post_data }) .then(function (response) { console.log(document.cookie) // const token = document.cookie.split('=')[1]; //请求成功,处理业务逻辑 console.log(response.data.csrfToken) // store.state.token =token // 保存token store.state.token =response.data.csrfToken }) .catch(function (error) { //请求失败,处理业务逻辑 console.log(error) }) }
如果不成功请留言我们一起解决
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。