title: I got 400 bad request on blacklist when I logout
body: <p>I'm trying to blacklist the user when the <code>logout</code> function called using <code> django-rest-framework-simplejwt</code>. I can logout from the page but I keep getting 400 bad request in terminal. I believe that the token is not destroyed yet and also in my APIview I got <code>&quot;detail&quot;: &quot;Method \&quot;GET\&quot; not allowed.&quot;</code>. Can you spot me the mistake?</p>
  <p>[ Updated ]</p>
  <p>error in terminal</p>
  <pre><code>Bad Request: /blacklist/
  [21/Aug/2020 10:06:24] &quot;POST /blacklist/ HTTP/1.1&quot; 400 0
  </code></pre>
  <p>settings.py</p>
  <pre><code>REST_FRAMEWORK = {
      'DEFAULT_PERMISSION_CLASSES': (
          'rest_framework.permissions.IsAuthenticated',
      ),
      'DEFAULT_AUTHENTICATION_CLASSES': (
          'rest_framework_simplejwt.authentication.JWTAuthentication',
      )
  }
  SIMPLE_JWT = {
      'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
      'REFRESH_TOKEN_LIFETIME': timedelta(days=14),
      'ROTATE_REFRESH_TOKENS': True,
      'BLACKLIST_AFTER_ROTATION': True,
      'ALGORITHM': 'HS256',
      'SIGNING_KEY': SECRET_KEY,
      'VERIFYING_KEY': None,
      'AUTH_HEADER_TYPES': ('JWT',),
      'USER_ID_FIELD': 'id',
      'USER_ID_CLAIM': 'user_id',
      'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
      'TOKEN_TYPE_CLAIM': 'token_type',
  }
  </code></pre>
  <p>views.py</p>
  <pre><code>class LogoutAndBlacklistRefreshToken(APIView):
      permission_classes = (AllowAny,)
      authentication_classes = ()
  
      def post(self, request):
          try:
              refresh_token = request.data[&quot;refresh_token&quot;]
              token = RefreshToken(refresh_token)
              token.blacklist()
  
              return Response(status=status.HTTP_205_RESET_CONTENT)
          except Exception as e:
              return Response(status=status.HTTP_400_BAD_REQUEST)
  </code></pre>
  <p>urls.py</p>
  <pre><code>urlpatterns = [
      path('', include(router.urls)),
      path('admin/', admin.site.urls),
      path(
          'blacklist/', LogoutAndBlacklistRefreshToken.as_view(),
          name=&quot;blacklist&quot;
      ),
      path('api-auth/', include('rest_framework.urls')),
      path(
          'api-token/', TokenObtainPairView.as_view(),
          name='token-obtain'
      ),
      path(
          'api-token-refresh/', TokenRefreshView.as_view(),
          name='token-refresh'
     ),
      path(
          'api-token-verify', TokenVerifyView.as_view(), 
          name='token-verify'
      ),
  ]
  </code></pre>
  <p>axios-base.js</p>
  <pre><code>import axios from &quot;axios&quot;;
  import store from &quot;../store/index&quot;;
  // API URL
  const ApiUrl = &quot;http://localhost:8000&quot;;
  
  const axiosBase = axios.create({
    baseURL: ApiUrl,
    headers: { ContentType: &quot;application/json&quot; },
  });
  
  const getAPI = axios.create({
    baseURL: ApiUrl,
  });
  
  getAPI.interceptors.response.use(undefined, function(err) {
    // if error response status is 401, it means the request was
    // invalid due to expired access token.
    if (err.config &amp;&amp; err.response &amp;&amp; err.response.status === 401) {
      // attempt to obtain new access token by running
      // 'refreshToken' action
      store
        .dispatch(&quot;refreshToken&quot;)
        .then((access) =&gt; {
          // if succesfull resend the request to get the data from server
          axios
            .request({
              baseURL: ApiUrl,
              method: &quot;get&quot;,
              headers: { Authorization: `Bearer ${access}` },
              url: &quot;/&quot;,
            })
            .then((response) =&gt; {
              // if successfully received the data store it in store.state.
              // APIData so that 'Downloads' component can grab the
              // data from it and display to the client.
              console.log(&quot;Success&quot;);
              store.state.APIData = response.data;
            })
            .catch((err) =&gt; {
              console.log(&quot;Got error while access token&quot;);
              return Promise.reject(err);
            });
        })
        .catch((err) =&gt; {
          return Promise.reject(err);
        });
    }
  });
  
  export { axiosBase, getAPI };
  </code></pre>
  <p>Vuex Store</p>
  <pre><code>import Vue from &quot;vue&quot;;
  import Vuex from &quot;vuex&quot;;
  import { axiosBase } from &quot;../api/axios-base&quot;;
  Vue.use(Vuex);
  
  export default new Vuex.Store({
    state: {
      accessToken: localStorage.getItem(&quot;access_token&quot;) || null, // makes sure the user is logged in even after
      // refreshing the page
      refreshToken: localStorage.getItem(&quot;refresh_token&quot;) || null,
      APIData: &quot;&quot;, // received data from the backend API is stored here.
    },
    getters: {
      loggedIn(state) {
        return state.accessToken != null;
      },
    },
    mutations: {
      updateLocalStorage(state, { access, refresh }) {
        localStorage.setItem(&quot;access_token&quot;, access);
        localStorage.setItem(&quot;refresh_token&quot;, refresh);
        state.accessToken = access;
        state.refreshToken = refresh;
      },
      updateAccess(state, access) {
        state.accessToken = access;
      },
      destroyToken(state) {
        state.accessToken = null;
        state.refreshToken = null;
      },
    },
    actions: {
      // run the below action to get a new access token on expiration
      refreshToken(context) {
        return new Promise((resolve, reject) =&gt; {
          axiosBase
            .post(&quot;/api-token-refresh/&quot;, {
              refresh: context.state.refreshToken,
            }) // send the stored refresh token to the backend API
            .then((response) =&gt; {
              // if API sends back new access and refresh token update the store
              console.log(&quot;New access successfully generated&quot;);
              context.commit(&quot;updateAccess&quot;, response.data.access);
              resolve(response.data.access);
            })
            .catch((err) =&gt; {
              console.log(&quot;error in refreshToken Task&quot;);
              reject(err); // error generating new access and refresh token because refresh token has expired
            });
        });
      },
      logoutUser(context) {
        if (context.getters.loggedIn) {
          return new Promise((resolve) =&gt; {
            axiosBase
              .post(&quot;/blacklist/&quot;)
              .then((response) =&gt; {
                localStorage.removeItem(&quot;access_token&quot;);
                localStorage.removeItem(&quot;refresh_token&quot;);
                context.commit(&quot;destroyToken&quot;);
                resolve(response);
              })
              .catch((err) =&gt; {
                localStorage.removeItem(&quot;access_token&quot;);
                localStorage.removeItem(&quot;refresh_token&quot;);
                context.commit(&quot;destroyToken&quot;);
                resolve(err);
              });
          });
        }
      },
    },
  });
  </code></pre>
  <p>Logout.vue</p>
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;h3&gt;Log out page&lt;/h3&gt;
      &lt;v-btn small color=&quot;success&quot; class=&quot;mr-2 mb-5&quot; @click=&quot;logout&quot;&gt;
        log out
      &lt;/v-btn&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    name: &quot;Logout&quot;,
    methods: {
      logout() {
        this.$store.dispatch(&quot;logoutUser&quot;).then(() =&gt; {
          this.$router.push({ name: &quot;Home&quot; });
        });
      },
    },
  };
  &lt;/script&gt;
  </code></pre>