【问题标题】:Angular http request with Django Rest JWT带有 Django Rest JWT 的 Angular http 请求
【发布时间】:2018-05-04 09:47:41
【问题描述】:

从 Angular 向我的 django 后端发送请求会返回未经授权的 401。这是注销功能的http请求。

import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { RequestOptions } from '@angular/http';
import { authLoginUrl,authLogoutUrl }  from '../../../../config/endpoints';
import 'rxjs/add/operator/map';
import { AlertService } from '../../../../../core/services/alert.service';
@Injectable()
export class LoginService{
    public token: string;

    constructor(private http: HttpClient) {
        // set token if saved in local storage
        var currentUser = JSON.parse(localStorage.getItem('currentUser'));
        this.token = currentUser && currentUser.token;
    }

    logout(): void {
        // notify backend of user logout
        //authLogoutUrl = "http://127.0.0.1:8000/api/auth/logout/"
        this.http.post(authLogoutUrl,{
            headers: new HttpHeaders().set('Authorization', 'JWT ' + this.token)
            })
            .subscribe()           
    }
}  

但是,当我通过 curl 发送请求时,请求被授权。

curl -X POST -H "Authorization: JWT <the_token>" http://localhost:8000/api/auth/logout/

注销视图在我的 django 后端:

class LogoutView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def post(self, request, format=None):
        logout(request)

        return Response({}, status=status.HTTP_204_NO_CONTENT)

一切似乎都运行良好。预检请求返回 200,但请求本身是未经授权的。这是请求标头

Request Headers

Cors 设置 django 休息:

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

#Rest Framework
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    'DEFAULT_PAGINATION_CLASS':
    'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE':100,
}

由于它适用于 curl 并且预检请求已获批准,我只能假设问题出在 angular 或 cors 上。

1) 标题设置是否正确? 2)这是一个cors问题吗?

【问题讨论】:

    标签: angular http django-rest-framework django-cors-headers


    【解决方案1】:

    问题是没有设置标题。我不确定为什么会这样,但我通过创建一个 Http 拦截器解决了这个问题。它拦截 http 请求并将 JWT 令牌添加到每个 http 请求的标头中。本文详细介绍了如何将拦截器做得非常好。

    https://theinfogrid.com/tech/developers/angular/building-http-interceptor-angular-5/

    这里也是拦截器代码。

    import { Injectable, Injector } from '@angular/core';
    import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
    
    import { Observable } from 'rxjs/Rx';
    import 'rxjs/add/observable/throw'
    import 'rxjs/add/operator/catch';
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
        private token: string;
        constructor() { }
    
        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
            this.getToken();
    
            console.log("intercepted request ... ");
    
            // Clone the request to add the new header.
            var authReq;
            if (this.token){
                authReq = req.clone({ headers: req.headers.set("Authorization", "JWT " + this.token)});
                console.log("Sending request with new header now ...");
            } else {
                authReq = req;
            }
            //send the newly created request
            return next.handle(authReq)
                .catch((error, caught) => {
                //intercept the respons error and displace it to the console
                console.log("Error Occurred");
                console.log(error);
                //return the error to the method that called it
                return Observable.throw(error);
            }) as any;
        }
    
        getToken() {
            let currentUser = JSON.parse(localStorage.getItem('currentUser'));
            this.token = currentUser && currentUser.token;
        }
    

    【讨论】:

    • 这个解决方案对我来说非常有效,我也面临同样的问题,它得到了修复,你是一个救命的人,感谢一百万!!!!
    猜你喜欢
    • 2018-05-02
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    相关资源
    最近更新 更多