我正在尝试创建一个(chrome 扩展 + Django)密码管理器,它将从表单中读取输入框,然后单击“提交”,它将向 Django 视图发出 POST 请求,其中的数据将存储到 postgresql 数据库中。 (请记住,这只是一个个人项目。)
但在每个请求中,我都会收到错误:Forbidden(未设置 CSRF cookie。)。即使我在检查的“应用程序”选项卡下看到 csrftoken cookie。我将 csrf 令牌与请求一起传递,所以我无法弄清楚错误是什么。
我尝试使用 Cookies.get('csrftoken') 从 cookie 中获取 csrf 令牌,并在从 Django 获取后设置 csrf 令牌 cookie。
这就是我在 Django 中的视图:
@ensure_csrf_cookie
def add(request):
if request.method == "POST":
website = request.POST['website']
username = request.POST['username']
password = request.POST['password']
user = request.user
encryptedPass = cryptography.crypto(password)
credentials = Credentials.objects.create(email=username, password=encryptedPass)
if Website.objects.filter(user = user.id).filter(name=website).exists():
website_obj = Website.objects.filter(user = user.id).filter(name=website)
# print(website_obj[0].credentials)
website_obj[0].credentials.add(credentials)
else:
website_obj = Website.objects.create(user=user, name=website)
website_obj.credentials.add(credentials)
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
return JsonResponse({'message':'Credentials Add'})
return redirect('add')
return render(request,'add.html')
这是我将 csrf 令牌传递给 chrome 扩展的视图:
@ensure_csrf_cookie
def get_csrf_token(request):
return JsonResponse({'csrfToken': django.middleware.csrf.get_token(request)})
我已经尝试了我的settings.py中的所有内容:
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',
'password_manager_app'
]
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',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
CSRF_TRUSTED_ORIGINS = ["*"]
CSRF_ALLOWED_ORIGINS = ["*"]
CSRF_COOKIE_DOMAIN = "*"
我正在 content-script.js 中使用 axios 发出发布请求:
export async function getCsrfToken(){
const axios = require('axios')
let token;
const response = await axios.get('http://localhost:8000/get-csrf-token',{withCredentials:true}).then((response)=>{
console.log(response.data.csrfToken)
token = response.data.csrfToken
})
return token
}
export async function axiosaddCredentialsToDatabase(email,password,url){
const token = await getCsrfToken()
const axios = require('axios')
axios.post('http://localhost:8000/add',{email,password,url},{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': token,
'X-Requested-With': 'XMLHttpRequest',
},
withCredentials:true
}).then((response)=>{
console.log(response)
})
}
如有任何意见,我将不胜感激。预先感谢:)
那是因为不知何故令牌没有被验证。
此外,不应只是为了检索此令牌而发送请求,Famework 中间件会将其设置为 cookie,因此您只需要检索它。否则,服务器将因令牌请求而过载(在现实世界环境中)。
这是一个最小的例子:
const 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();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
const csrftoken = getCookie("csrftoken");
const data = {
email: "[email protected]",
password: "supersecret",
url: "https://example.com"
};
const headers = {
"Content-Type": "application/json",
"X-CSRFToken": csrftoken,
};
const sendRequest = async () => {
try {
const response = await axios.post("/add/", data, { headers });
console.log(response.data);
} catch (error) {
console.log(error);
}
};
sendRequest();