简体   繁体   中英

Different headers used in Axios patch

I spent an hour looking in the Chrome console and I cannot see where this bug comes from.

I am finishing an update of OAuth implementation in my Vue app.

The story begins when socialLink.js finds out that a new user must be created. Vue component Vue-authentication depends on the presence of access_token in a response so I return some dummy text:

return api.sendResponse(res, { email, name, socialId, access_token: 'abcd' });

The library stores this value in localStorage :

本地存储截图

After a redirect, the SignUp.vue is rendered and I complete the form. The first communication with the server is a Vuex call to create a new user:

response = await this.$store.dispatch('CREATE_USER_PROFILE', payload);

Which returns a real short lived JWT token:

const token = auth.createToken(userId, nickname, new Date(), null, false, '1m');
return api.sendCreated(res, api.createResponse(token));

Which I store in the Vue page afterwards:

const { data } = response;
const token = data.data;
if (token === undefined) {
  this.error = this.$t('sign-up.something-went-wrong');
  return false;
}

I checked that the token contains what the server returned:

Request URL: https://beta.mezinamiridici.cz/api/v1/users
Request Method: POST
Status Code: 201 Created

{"success":true,"data":"eyJhbGciOiJIUzI1NiIs...Tl8JFw2HZ3VMXJk"}

Then I call another Vuex method and pass the current JWT token:

await this.$store.dispatch('UPDATE_USER_PROFILE', {

I checked in the Vuex devtools that there really is the correct JWT token. I then pass it further to api.js .

Here I create an Axios configuration holding an Authorization header:

function getAuthHeader(context, jwt = undefined, upload) {
  const config = { headers: { } };
  if (jwt || (context && context.rootState.users.userToken)) {
    config.headers.Authorization = `bearer ${jwt || context.rootState.users.userToken}`;
  }

Again, I checked that the correct JWT token is used there.

Finally, I pass all data to Axios:

function patch(endpoint, url, body, context, jwt) {
  const headers = getAuthHeader(context, jwt);
  console.log(headers);
  if (endpoint === 'BFF') {
    return axios.patch(`${VUE_APP_BFF_ENDPOINT}${url}`, body, headers);
  } else {
    return axios.patch(`${VUE_APP_API_ENDPOINT}${url}`, body, headers);
  }
}

Which I log and can confirm the correct JWT is still there:

bearer eyJhbGciOiJIUzI1N....8JFw2HZ3VMXJk

There is nothing that could change the header now to abcd , but, the 'Network' tab shows it:

网络选项卡屏幕截图

And the server fails with a parse error.

Has anybody got an idea why Axios uses the Authorization header with a different value than I pass it?

Ok, mystery solved. vue-authenticate is the reason, because, it creates Axios interceptors and handles the Authorization header itself.

vue-authenticate.common.js :

var defaultOptions = {
  bindRequestInterceptor: function ($auth) {
    var tokenHeader = $auth.options.tokenHeader;

    $auth.$http.interceptors.request.use(function (config) {
      if ($auth.isAuthenticated()) {
        config.headers[tokenHeader] = [
          $auth.options.tokenType, $auth.getToken()
        ].join(' ');
      } else {
        delete config.headers[tokenHeader];
      }
      return config
    });
  },

My code is more complex and it supports internal accounts with email/password so this code is breaking mine. The interceptor must be present and be a function, so the solution was:

Vue.use(VueAuthenticate, {
  tokenName: 'jwt',
  baseUrl: process.env.VUE_APP_API_ENDPOINT,
  storageType: 'localStorage',
  bindRequestInterceptor() {},
  bindResponseInterceptor() {},
  providers: {
    facebook: {
      clientId: process.env.VUE_APP_FACEBOOK_CLIENT_ID,
      redirectUri: process.env.VUE_APP_FACEBOOK_REDIRECT_URI,
    },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM