2017-11-18 166 views
0

我遇到的問題在任何地方發現我遇到的問題(我認爲)我從Angular 4發送到Django的HTTP請求中的授權標頭Rest框架API我已經創建。讓我們着手進行:對Django Rest Framework的角度4 HTTP請求

編輯: 證實了這個問題,因爲我也使用Django-CORS-標題現在擺脫自己的CORS問題的4200端口(因爲它被認爲是一個不同的關於授權起源)。問題仍然存在,只是在向API發送請求時收到「未經授權」的消息。我開始認爲這是一個編碼問題,因爲當我嘗試用httpie以下的請求將顯示以下信息:

http GET http://localhost:8000/api/groups/ "Authorization: Basic admin:password" 

,然後顯示的消息:

{ 
    "detail": "Invalid basic header. Credentials not correctly base64 encoded." 
} 

在設置。 py,我確定已經有了一個權限類和認證類。

REST_FRAMEWORK = { 
'DEFAULT_AUTHENTICATION_CLASSES': [ 
    'rest_framework.authentication.BasicAuthentication', 
], 
'DEFAULT_PERMISSION_CLASSES': [ 
    'rest_framework.permissions.IsAdminUser' 
], 

... 

CORS_ORIGIN_WHITELIST = [ 
    'localhost:4200', 
] 

在views.py,這也許是在我的錯,因爲是在控制檯錯誤嘗試發送從角的要求時,我得到 - > REST API是「否‘訪問控制允許來源’標題出現在請求的資源上。'這是不真實的,因爲當我刪除認證需求時,它不會抱怨這一點。

class UserViewSet(viewsets.ModelViewSet): 
    queryset = User.objects.all().order_by('-date_joined') 
    serializer_class = UserSerializer 
    permission_classes = (IsAdminUser,) 
    authentication_classes = (BasicAuthentication,) 

    def list(self, request): 
     queryset = User.objects.all().order_by('-date_joined') 
     serializer = UserSerializer(queryset, many=True, context={'request': request}) 
     return Response(serializer.data, 
         status=200) 

的角度dev的服務器在本地主機上運行:4200,而Django是留在其本地主機的默認值:8000。

我會包括良好的措施的urls.py:

from django.conf.urls import url, include 
from rest_framework import routers 
from backend.api import views 
from django.contrib import admin 

router = routers.DefaultRouter() 
router.register(r'users', views.UserViewSet) 
router.register(r'groups', views.GroupViewSet) 
router.register(r'info', views.InfoViewSet) 

urlpatterns = [ 
    url(r'^api/', include(router.urls)), 
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 
    url(r'^admin/', admin.site.urls), 
] 

請注意,我可以請求和使用授權頭,像這樣得到迴應就好用httpie:

http GET http://localhost:8000/api/users/ -a admin:password 

最後,這裏是發出請求的角碼(包括我的一切,使進口可以被檢查爲好):

​​

我也導入了HttpClientModule,並將其列在我的app.module的'imports'下。

+0

Hi ..try to his.http.get (url) –

回答

2

單獨的端口被認爲是不同的起源,所以你當然會在本地主機上獲得一個跨域錯誤(CORS)。這是您的服務器的瀏覽器安全功能。

安裝django-cross-header包來解決跨域錯誤。

+1

它似乎不是一個CORS問題,我查看了django-cors-headers。如果有的話,授權有問題,但我還無法弄清楚是否它是我添加標題的方式,如果它是django身份驗證或其他選擇的副作用...我添加了django-cors-headers以獲得較好的效果,但什麼也沒有變。 –

+0

[看這裏](https://stackoverflow.com/questions/43357687/django-python-rest-framework-no-access-control-allow-origin-header-is-present)。我遇到了類似的問題,其中一個建議的原因是,使用auth通過設計實施更嚴格的策略。我用這個,它得到了resoved。不同之處在於我們使用的是Angular 2和django,但這個問題通常與瀏覽器而不是前端框架相關聯。 – kmcodes

+0

感謝您的幫助,我認爲使用django-cors-headers解決了問題的一部分,我只是不知道這裏有兩個問題!我最終通過使用您的解決方案並使用用戶名:密碼部分的'btoa'函數對授權標頭進行編碼來實現它。 –

1

我用的是相同的後端框架,我已經找到了解決辦法是建立我的項目使用

ng build --production -host=myDomain.com // try localhost -p 8080 in your case 

和正確的主機更換

Access-Control-Allow-Origin: 'http://localhost:4200' 

Access-Control-Allow-Origin: '*' 
1

問題以兩種方式解決。首先,我沒有正確確定從Angular 4發送請求的原點開始啓用CORS。使用django-cors-headers的@kmcodes解決方案是一個很好的解決方案,並且在將它添加到我的項目後,我不再遇到'Access-Control-Allow-Origin'缺失的問題。

問題的第二部分是在我把到由角4.發送請求的首標是如下中我所需要的變化,使:

this.http.get(
     'http://localhost:8000/api/users/', 
     { headers: new HttpHeaders().set('Authorization', 'Basic admin:password'), } 
    ).subscribe(
     data => { 
      this.results = data; 
     }, 
     err => { 
      console.log("ERROR RETREIVING USERS"); 
     }); 

向該:

this.http.get(
     'http://localhost:8000/api/users/', 
     { headers: new HttpHeaders().set('Authorization', 'Basic ' + btoa('admin:password')), } 
    ).subscribe(
     data => { 
      this.results = data; 
     }, 
     err => { 
      console.log("ERROR RETREIVING USERS"); 
     }); 

我得到了使用httpie來檢查我的請求時的提示,並看到當我沒有使用-a標誌來添加驗證參數而是使用'Authorization'標頭時。這給了我一個錯誤,指出請求失敗,出現錯誤代碼401,未經授權,因爲username:password部分未使用base64進行編碼。在Angular 4(也許之前),btoa()解決了上述問題。

+0

當我正在解決基於HTTP請求的問題時,我還使用[requestbin](https://requestb.in/)。 – kmcodes