仅当用户登录时从 Angular 发送 Post-requests 时,Django 403 被禁止

2023-12-08

我已经创建了一个后端 Django 应用程序,目前正在连接一个 Angular 前端,该前端使用 Django Rest 框架从 API 设置中请求数据,并且遇到了我登录的用户(在后端)的问题,他们在前端登录并不重要)对 API 的所有后期请求都会收到 403 错误。我认为这是因为 Django 中的 CSRF 保护。

我查看了一个解决这个问题的线程,并尝试实现该解决方案从这个线程没有运气。

注销的用户可以发送注册或登录的后请求。但是,当登录用户尝试时,会收到 403 错误。在浏览 DRF API 时发送相同的数据是成功的,这就是为什么我认为它与 CSRF 有关。更清楚地说,如果我以前端用户身份登录并尝试登录或注册新用户(这些部分在开发中不会被阻止),我会收到 403 响应。如果我登录可浏览的 API 并发送完全相同的帖子内容,它可以成功尝试再次登录或注册新用户。

难道是因为我添加的自定义标头可能会替换 CSRF 标头?在这种情况下,我该如何重新制作它,因为需要该标头,否则我会得到 415 不支持的媒体类型。

下面是 Angular 服务,它提供了向服务器发送登录请求的功能:

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators'
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Userlogon } from '../_models/Userlogon';
import { User } from '../_models/User';

const HttpOptions = {
  headers: new HttpHeaders({ "Content-type": "application/json" })
};

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  loginobject: any;
  private usersUrl= '/api/v1/accounts/';
  private logonUrl= '/api/v1/auth/login/';
  private logoutUrl= '/api/v1/auth/logout/';

  constructor(
    private http: HttpClient
  ) { }

  login(username: string, password: string) {
    this.loginobject=JSON.stringify({"username": username, "password": password});
    return this.http.post<any>(this.logonUrl, this.loginobject, HttpOptions)
      .pipe(map(user => {
        if (user){
          console.log("If statement satisfied");
          localStorage.setItem('currentUser', JSON.stringify(user));

        }
        return user;
      }));
  }

  logout(){
    localStorage.removeItem('currentUser');
    return this.http.get<any>(this.logoutUrl).subscribe(response => console.log(response));
  }
}

这是我在其中实现了提供程序选项的应用程序模块:

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http'

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { RegisterComponent } from './register/register.component';
import { LoginComponent } from './login/login.component';
import { AlertComponent } from './_directives/alert.component';
import { ProfileComponent } from './profile/profile.component';
import { AuthGuardService } from './_guards/auth-guard.service';
import { AlertService } from './_services/alert.service';
import { AuthService } from './_services/auth.service';
import { UserService } from './_services/User.service';

@NgModule({
  declarations: [
    AppComponent,
    RegisterComponent,
    LoginComponent,
    AlertComponent,
    ProfileComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule,
    HttpClientModule,
    HttpModule
  ],
  providers: [
    {
      provide: XSRFStrategy,
      useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

这是 Django 处理的模板:

{% load static %}
{% csrf_token %}
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularWebapp</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
  <app-root></app-root>
{% block javascript %}
<script type="text/javascript" src="{% static 'runtime.js' %}"></script><script type="text/javascript" src="{% static 'polyfills.js' %}"></script><script type="text/javascript" src="{% static 'styles.js' %}"></script><script type="text/javascript" src="{% static 'vendor.js' %}"></script><script type="text/javascript" src="{% static 'main.js' %}"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
{% endblock %}
</body>
</html>

最后是 Django 视图代码:

from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from rest_framework import permissions, viewsets, status
from rest_framework.views import APIView
from rest_framework.response import Response
from authentication.models import Account
from authentication.permissions import IsAccountOwner
from authentication.serializers import AccountSerializer, LoginSerializer
from getorgname import scrapeorg, idgenerator
import json

# Create your views here.

class AccountViewSet(viewsets.ModelViewSet):
    lookup_field='username'
    queryset=Account.objects.all()
    serializer_class= AccountSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer=self.serializer_class(data=request.data)

        if serializer.is_valid():
            newuser=serializer.validated_data
            Account.objects.create_user(
                username=newuser.get('username'),
                email=newuser.get('email'),
                org_name=scrapeorg(newuser.get('org_number')),
                org_number=newuser.get('org_number'),
                cid=idgenerator(),
                utype=newuser.get('utype'),
                password=newuser.get('password'),
                )
            #Account.objects.create_user(**serializer.validated_data)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

        return Response({
            'status': 'Bad request',
            'message': 'Account could not be created with received data',
        }, status=status.HTTP_400_BAD_REQUEST)

class LoginView(APIView):
    def post(self, request):
        #data=json.loads(request.body)
        serializer=LoginSerializer(data=request.data)
        if serializer.is_valid():
            data=serializer.validated_data
            username=data.get('username')
            password=data.get('password')

            account=authenticate(username=username, password=password)

            if account != None:
                login(request, account)

                serialized = AccountSerializer(account)

                return Response(serialized.data)

            else:
                return Response({
                    'status': 'Unauthorized',
                    'message': 'Username %s and password invalid' % username 
                }, status=status.HTTP_401_UNAUTHORIZED)
        return Response({
                'status': 'Bad request',
                'message': 'Invalid data for a login request',
            }, status=status.HTTP_400_BAD_REQUEST)

class LogoutView(APIView):
    def get_permissions(self):
        return (permissions.IsAuthenticated(), IsAccountOwner(),)
    def get(self, request):
        logout(request)
        return Response({
            'status': 'Success',
            'message': 'Successfully processed logout request',
        })

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅当用户登录时从 Angular 发送 Post-requests 时,Django 403 被禁止 的相关文章

随机推荐

  • 如何用 C++ 从文件中读取单词?

    所以我觉得很无聊 决定制作一款刽子手游戏 我在高中第一次学习 C 时就做过这样的作业 但这是在我接触几何之前 所以不幸的是我在任何方面都没有做得很好 学期结束后我一怒之下把所有东西都扔掉了 我想要制作一个txt文档 然后输入一大堆单词 IE
  • Java 关闭挂钩

    使用 IntelliJ IDE java 1 8 IDE 中的 lang level 6 以及命令提示符下的默认值 从命令行 Windows 7 编译并运行 javac cp Main java java cp Main 给出以下代码 我想
  • 在 Fine Uploader 中,如何编辑/更新先前会话中上传的文件的 S3 文件元数据?

    我有一个要求 用户需要编辑 更新在之前的会话中上传的 s3 文件元数据 我已经实现了初始文件列表 但我需要使文件元数据 文件名 标题 在我的情况下是新字段 在显示列表中可编辑 能实现吗 I see 编辑文件功能 但这仅限于文件上传之前 看来
  • 使用绑定和 AJAX 下拉

    我是 ColdFusion 的新手 刚刚开始学习 Ajax 我的问题是 我在网上发现了一些很酷的编码来实现两个下拉菜单 其中第二个菜单取决于第一个菜单中选择的内容 但目标是从选择查询中提取下拉列表中的所有值 我正在使用我刚刚了解到的绑定功能
  • 在python3中输出十六进制值

    我正在使用 python3 编写 shellcode 漏洞 但是 当我尝试输出一些十六进制字节时 例如使用线路 python3 c print x8c xxd 中的值xxd is c28c 而不是预期的8c python2中不会出现这个问题
  • 为什么在添加元素以设置映射多对多时,休眠会从连接表中删除行?

    假设我有两个课程 class A Set b bs class B 这个映射 b
  • Java——创建一个新线程

    我是线程新手 我想创建一些与主线程分开工作的简单函数 但这似乎不起作用 我只想创建新线程并独立于主线程上发生的事情在那里做一些事情 这段代码可能看起来很奇怪 但到目前为止我对线程还没有太多经验 你能解释一下这有什么问题吗 public st
  • 检查属性是否存在

    是否可以检查是否存在使用魔术设置器设置的属性 class Test private vars public function set key value this gt vars key value public function get
  • Java 中向上转换的问题?

    有人可以解释一下为什么会发生这种情况吗 class Apple String type setType System out println inside apple class this type apple class RedApple
  • Android Robotium:单击/启动另一个活动后如何返回到正在测试的活动

    我的 Robotium 测试有问题 在我的一项活动 A 中 我单击了一个按钮 单击此按钮会启动另一个活动 B 因此 在我的 robotsium 测试中 我有这样的内容 Button myBtn Button solo getView R i
  • 从条件格式语句中计算彩色单元格的数量

    所以我今天重新回顾一下昨天的事情 多列vlookup条件格式 使用 Scott Holtzman 提供的条件格式声明 一切都按预期运行 感谢 Scott 现在我遇到了一个小问题 我需要根据背景颜色对各个单元格进行计数 并将其显示在另一张纸中
  • php preg_replace 匹配

    如何将 preg replace 中的匹配项作为可用变量访问 这是我的示例代码
  • 为什么我们不能将数组传递给可以使用 &array[0] 的函数

    void fun int array int main int array 1 2 3 fun array gt 1 error in this line return 0 error cannot convert int 3 to int
  • 导入隐式转换而不使用 SparkSession 实例

    我的 Spark 代码中充满了这样的代码 object Transformations def selectI df DataFrame DataFrame needed to use to generate ColumnName impo
  • 类声明之间的区别

    我看到一些关于这个主题的类似问题 但我想确定一下 所以我问 有什么区别 class MyClass pass and class MyClass pass 另外 这两者之间有区别吗 class MyClass pass class MyCl
  • 什么是递归以及何时应该使用它?

    Locked 这个问题及其答案是locked因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 邮件列表和在线讨论中似乎经常出现的主题之一是获得计算机科学学位的优点 或缺乏优点 对于消极方来说 似乎一次又一次出现的一个论点是
  • .net thread.sleep 不准确

    我快疯了 我通过 gsm 发送音频 根据语音规范 我必须发送语音数据包 然后等待 20 毫秒才能获得正常语音 我使用system threading thread sleep 20 但是 我注意到声音很慢 但是当我运行另一个不同的应用程序时
  • SecurityError:操作不安全 - window.history.pushState()

    我在 Firefox 控制台中收到此错误 SecurityError The operation is insecure罪魁祸首是 HTML5 功能 window history pushState 当我尝试使用 AJAX 加载某些内容时
  • pandas 三路连接列上的多个数据框

    我有 3 个 CSV 文件 每个数据框中的第一列都是人名 字符串 而每个数据框中的所有其他列都是该人的属性 如何将所有三个 CSV 文档 连接 在一起以创建一个 CSV 其中每一行都具有人员字符串名称的每个唯一值的所有属性 The join
  • 仅当用户登录时从 Angular 发送 Post-requests 时,Django 403 被禁止

    我已经创建了一个后端 Django 应用程序 目前正在连接一个 Angular 前端 该前端使用 Django Rest 框架从 API 设置中请求数据 并且遇到了我登录的用户 在后端 的问题 他们在前端登录并不重要 对 API 的所有后期