'Axios doesn't send headers from request interceptors
On my front-end I have this Axios code:
import axios from "axios";
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
const apiUrl = process.server ? `${process.env.FRONT}api/` : '/api/';
const api = axios.create({
baseURL: apiUrl,
headers: {
'Content-Type': 'application/json'
}
})
api.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
if (token) {
config.headers.common['Authorization'] = 'Bearer ' + token
}
return config;
}, function (error) {
return Promise.reject(error);
});
export const login = async (payload) => {
const { data } = await api.post(`login`, payload)
return data
}
What this code does is just set some headers with token. Then, this request goes to front-end server:
router.post(`/login`, async (req, res) => {
try {
const data = await api.post('/login', req.body)
res.json(data.data)
} catch (e) {
res.status(e.response.status).json(e.response.data)
}
})
If you do console.log(req.headers) here, it's gonna be okay, headers will look like this:
req.headers {
accept: 'application/json, text/plain, */*',
'content-type': 'application/json',
host: 'localhost:8010',
connection: 'keep-alive',
'content-length': '898',
authorization: 'Bearer ...token...',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36',
...
}
And here is the problem, after that, when request goes to back end, it's captured by middleware auth:
router.post('/login', auth, accountController.login)
This is how this middleware looks like:
import * as jwtService from './../services/jwtService';
import { Request, Response } from 'express';
import { CommonResponse } from "../responses/response";
export default async (req: Request, res: Response, next: any) => {
try {
if (req.headers.authorization) {
const user = await jwtService.getUser(req.headers.authorization.split(' ')[1])
if (user) next();
else return CommonResponse.common.unauthorized({ res })
} else {
return CommonResponse.common.unauthorized({ res })
}
} catch (e) {
return CommonResponse.common.unauthorized({res});
}
}
And here is the problem, if you do console.log(req.headers) here you'll see, this:
{
accept: 'application/json, text/plain, */*',
'content-type': 'application/json',
'user-agent': 'axios/0.26.0',
'content-length': '898',
host: 'localhost:3000',
connection: 'close'
}
What happened to my headers?
By the way, if on front end server you do this:
const data = await api.post('/login', req.body, {headers: req.headers})
This is going to work, but still, what happened? Is this how interceptors should work?
Solution 1:[1]
Change your code of interceptors as follows:
api.interceptors.request.use(function (config) {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = 'Bearer ' + token
}
return config;
}, function (error) {
return Promise.reject(error);
});
And in middleware you should use Authorization instead of authorization like:
import * as jwtService from './../services/jwtService';
import { Request, Response } from 'express';
import { CommonResponse } from "../responses/response";
export default async (req: Request, res: Response, next: any) => {
try {
if (req.headers.Authorization) { // correct this line
const user = await jwtService.getUser(req.headers.Authorization.split(' ')[1]) // correct this line
if (user) next();
else return CommonResponse.common.unauthorized({ res })
} else {
return CommonResponse.common.unauthorized({ res })
}
} catch (e) {
return CommonResponse.common.unauthorized({res});
}
}
And make sure that you have token in localStorage too and provide feedback if still facing issue.
Solution 2:[2]
There seems to be no issue with code.
Try this demo and it works fine. https://github.com/indolent-developer/axiosDemo
Most probably you are having issue with localstorage. Generally I like to avoid if without else. Can you can some console logs and see it is working fine.
Solution 3:[3]
Maybe the reason behind it is that you're assigning to request.headers.common.
It works for me when I assign to req.headers
api.interceptors.request.use(
(req) => { // I'm using req instead of config just for clarity
req.headers['Authorization'] = `token ${token}`
return req;
},
(err) => {
return Promise.reject(err);
}
);
In your server side, change req.headers.authorization to req.headers.Authorization
import * as jwtService from './../services/jwtService';
import { Request, Response } from 'express';
import { CommonResponse } from "../responses/response";
export default async (req: Request, res: Response, next: any) => {
try {
if (req.headers.Authorization) {
const user = await jwtService.getUser(req.headers.authorization.split(' ')[1])
if (user) next();
else return CommonResponse.common.unauthorized({ res })
} else {
return CommonResponse.common.unauthorized({ res })
}
} catch (e) {
return CommonResponse.common.unauthorized({res});
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Asad Haroon |
| Solution 2 | indolentdeveloper |
| Solution 3 |
