如何使用 Django 和 React 设置 csrf 令牌
·
从安全角度来看,我不确定这个实现是否完全正确,但我想写这篇文章,因为我发现设置 django 并使用 csrf 做出反应时存在一些问题。
我在用着:
-
Django 4.0
-
反应 17
-
django-cors-headers
zoz100005 axios
这是我为文件setting.py设置的
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders', //<------cors
'api'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'corsheaders.middleware.CorsMiddleware', //<------cors
'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',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS=["http://localhost:3000", "http://127.0.0.1:3000"]
CSRF_TRUSTED_ORIGINS = ["http://localhost:3000", "http://127.0.0.1:3000"]
这是我获取 csrf 令牌的观点,使用装饰器 ensure_csrf_cookie,将在 http 响应中添加一个 set-cookie,因此我们将在浏览器中找到我们的 csrftoken cookie
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def get_csrf(request):
return JsonResponse({})
对于前端,在我们请求获取令牌之前调用我们的视图很重要,如果令牌已经存在,则将更新过期时间。
const get_csrf = () => axios.get('http://localhost:8000/api/get_csrf').then(res => {})
获得 cookie 后,我们可以执行 POST
axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = 'X-CSRFToken'
axios.defaults.withCredentials = true
axios.post('http://localhost:8000/api/upload_data', { 'test': 'ok' }).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
axios.defaults.xsrfCookieName u003d 'csrftoken'
axios.defaults.xsrfHeaderName u003d 'X-CSRFToken'
如果您想手动设置,将为您自动设置标头(对于每个请求),您可以通过这种方式获取 csrf 令牌
// from django website https://docs.djangoproject.com/en/4.0/ref/csrf/
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
或使用这个库
-
npm i js-cookie
-
npm i@types/js-cookie(如果您使用的是打字稿)
并手动设置http post请求的标头
const csrftoken = Cookies.get('csrftoken')
axios.post('http://localhost:8000/api/upload_data',
{ 'body_data': 'ok' },
{ headers: { 'X-CSRFToken': csrftoken }}
).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
更多推荐
所有评论(0)