1

Sending a request to my django backend from angular returns a 401 unauthorized. Here is a http request on a logout function.

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()           
    }
}  

However request is authorized when I send it through curl.

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

The logout view is in my django backend:

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

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

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

Everyting seems as though it is working alright. The preflight request returns 200, but the request itself is unauthorized. Here are the request headers

Request Headers

Cors settings django rest:

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,
}

Since it works with curl and the preflight request is approved, I can only assume the problem is with angular or cors.

1) Are the headers set correctly? 2) Is this a cors problem?

1 Answer 1

2

The problem was that the header was not being set. I'm not sure why this was the case, but I solved this by creating a Http Interceptor. It intercepts http requests and adds the JWT token to the headers for each http request. This article goes over making an Interceptor really well.

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

Here is the interceptor code as well.

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;
    }
Sign up to request clarification or add additional context in comments.

1 Comment

this solution worked perfectly fine for me i was facing the same issues and it got fixed you're a life saver man thanks a Million!!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.