【毕业设计】前后端分离——解决cookies跨域

🌈据说,看我文章时 关注、点赞、收藏帅哥美女们 心情都会不自觉的好起来。

前言:
🧡作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
✨个人主页:点我直达,在这里肯定能找到你想要的~
👍专栏介绍:个人记账分析系统 ,专门记录制作过程,每天进步一点点~

想看往期历史文章,可以浏览此博文: 历史文章目录,后续所有文章发布都会同步更新此博文~

人生苦短,我用python

跨域问题

Django 在前端发送 POST 请求的时候会带上 csrf_token ,但这是由模板自动渲染的,所以这里先尝试跨域使用模板。
一开始使用 vue.js ,默认端口 3000 ,如果使用 iframe 加载 Django 模板页面的话,就会触发跨域问题:

在这里插入图片描述

要解决这个问题找遍互联网,发现要在设置里加上:

X_FRAME_OPTIONS = 'ALLOW-FROM http://127.0.0.1:3000'
CSRF_TRUSTED_ORIGINS = ['127.0.0.1:3000']
CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_NAME = 'csrf'

此时页面能正常显示了,其中 X_FRAME_OPTIONS 选项的 ALLOW-FROM http://127.0.0.1:3000 属于过时语法,不会生效,但肯定不会被设置成默认的 DENY 属性,当然这里也不能设置他唯二有用的属性 SAMEORIGIN 因为这只是让同源可以加载在 iframe 里,我们这里端口不一样,不同源,你哪怕值为空也好。

在这里插入图片描述
但是这样处理后 cookie就只能限制于 iframe 里了,所以最终决定整个项目还是使用前后端完全分离的形式,单独获取 csrf_token
还发现一个问题,Django 处理 csrf_token 的时候,本地域名必须是 127.0.0.1 ,而不能是 localhost ,换句话说,Django 处理的时候必须经过网卡( localhost 是不经过网卡的)。
Django 发送 POST 请求时候,Django 的返回:

在这里插入图片描述

解决跨域问题

简单点解决:

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def XXX(request):
    if request.method == 'POST':
        ...

这样这个视图就临时不受 csrf 保护了,自然不会去验证 csrf_token 了,不过前后端分离使得我想直接应用在全部函数上,就直接把中间件去掉吧:

MIDDLEWARE = [
    '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',
]

settings.py 里注释掉 MIDDLEWARE 中注释掉 django.middleware.csrf.CsrfViewMiddleware 即可关闭 csrf 中间件了。
如果需要在启用 csrf 的情况下获取 csrf_token ,只需要新建一个获取的视图,使用如下方法:

import json
from django.shortcuts import HttpResponse
from django.middleware.csrf import get_token
def XXX(request):
    return HttpResponse(json.dumps({'token': get_token(request)}), content_type="application/json,charset=utf-8")

不过跨域后 csrf_token 就基本失去了原来的防止 csrf 攻击的意义,所以干脆还是直接关闭。

多维度解决跨域问题

刚才那些只是简单尝试发现可以,为了稳妥起见,前端后端各上一层保险方法:

Django跨域

  1. 安装 django-cors-headers 扩展:pip install django-cors-headers
  2. 添加 appINSTALLED_APPS = ['corsheaders']
  3. 在之前注释的基础上添加新的中间件:
MIDDLEWARE = [
    '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',
    'corsheaders.middleware.CorsMiddleware'  # 新添加的中间件
]
  1. settings.py 文件中添加白名单:
CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:3000',
    'https://127.0.0.1:3000',
    'http://localhost:3000',
    'https://localhost:3000',
)
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

Vue3跨域

虽然是 vue 跨域,但实际上修改的是 vue 脚手架 vite 的配置,打开 vite.config.js 文件,里面粘贴如何代码:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
const { resolve } = require('path')

// https://vitejs.dev/config/
export default defineConfig({
	// 起个别名,在引用资源时,可以用‘@/资源路径’直接访问
	resolve: {
		alias: {
			"@": resolve(__dirname, "src"),
		},
	},
	plugins: [vue()],
	// 配置前端服务地址和端口
	server: {
		host: '0.0.0.0',
		port: 3000,
		// 是否开启 https
		https: false,
	},
	// 设置反向代理,跨域
	proxy: {
		'/api': {
			// 后台地址
			target: 'http://127.0.0.1:8000/api/',
			changeOrigin: true,
			rewrite: path => path.replace(/^\/api/, '')
		},
	}
})

这样前端跨域代理就设置完成了。
据看到的资料表示,这反向代理是针对 axios 的,我暂时不用这个模块,所以也不实验验证是否成功了。

补充说明

如果对跨域是否成功还不自信的话,可以添加以下代码让自己更安心一点,其中 * 可以改成自己的前端域名~

response = HttpResponse('')
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Credentials'] = 'true'

有一个深坑,就是 HBuilder X 启动的 vue 服务默认是 http://localhost:3000/ ,但这不经过网关!不经过网关就无法跨域设置 cookie !!!刚刚本博主就特别纳闷怎么回事,无意间将 localhost 改成 127.0.0.1 ,问题瞬间迎刃而解~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值