CSRF令牌 * 似乎 * 妨碍了
我正在为我的应用程序编写django测试,我的一个视图允许用户“喜欢”其他用户的帖子。但是测试失败了,问题 * 似乎 * 是没有CSRF令牌,但我不确定是否是真的。POST数据不被视图使用,它只使用url数据,我这么说的唯一原因是因为我写的其他测试也有类似的问题,并且解决了这个问题,但是我尝试的任何东西都不起作用
下面是我测试:
from django.test import TestCase, Client
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.middleware.csrf import get_token
from .views import update
from .models import Post, Like
def setUp(self):
# creates a user and logs into the client
self.user = User.objects.create_user(username='testuser', password='testpass')
self.client = Client()
self.client.force_login(self.user)
--- some code ommited ---
def test_like_view(self):
# make a post
p1 = Post.objects.create(title='title', body='body', published_date=timezone.now(), created_by=self.user)
# get CSRF token
response = self.client.get(f'/{p1.id}/update/')
csrf_token = response.cookies['csrftoken'].value
# send POST request with CSRF token
response = self.client.post(f'/{p1.id}/like/', {'csrfmiddlewaretoken': csrf_token})
# check that the response status code is 302, indicating a redirect
self.assertEqual(response.status_code, 302)
# check that a Like object was created
self.assertTrue(Like.objects.filter(post=p1).exists())
这是我的观点
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.utils import timezone
from django.db.models import Count
from django.contrib.auth.decorators import login_required
from .models import Post, Like
--- some code ommited ---
@login_required
def like(request, pk):
#users cannot like posts that they have allready liked in the past
post = Post.objects.get(id=pk)
l = Like(users = request.user, posts = post)
all_likes = Like.objects.all()
for like in all_likes:
if l.users == like.users and l.posts == like.posts:
return HttpResponseRedirect('..')
l.save()
return HttpResponseRedirect('..')
我手动测试了视图,我知道它工作的事实,当使用microsoft edge中的dev工具时,我看到一个csrf令牌正在传输。
1条答案
按热度按时间cvxl0en21#
拥有一个csrf_token和登录是两件不同的事情。匿名用户仍然可以获得一个令牌,这样服务器就可以识别客户端。
我建议只使用
self.client.login()
命令,我已经使用它取得了很多成功,而且我从来没有手动为任何POST或GET提供令牌这是我格式化测试和登录的一般方式:
我总是通过
def test_()
登录,因为我总是测试登录装饰器是否存在。如果我在安装过程中登录,我将不得不注销。我也只是使匿名测试成为一个函数,并只传递URL和self
(输入较少)