I have the following code written in TypeScript and using Express:
app.use((req, res, next) => {
if (!process.env.UNIVERSAL_FS_PASSWORD) {
throw new Error(
"An environment variable UNIVERSAL_FS_PASSWORD is required to protect your files"
);
}
if (!req.headers.authorization) {
return res
.json({success: false, error: "An Authorization header is required"})
.status(401);
}
if (
!bycrypt.compareSync(
process.env.UNIVERSAL_FS_PASSWORD,
(req.headers.authorization as string).replace(/^Bearer\s/, "")
)
) {
return res
.json({success: false, error: "Unauthorized request"})
.status(401);
}
next();
});
It uses middleware to check for authorization and other key details. When I send an invalid authorization header I get the expected response. However, the status code is 200.
Here are my HTTP headers:
| Key | Value |
| -------- | -------------- |
| Accept | */*
|
| User-Agent | Thunder Client (https://www.thunderclient.com)
|
| Authorization | test
I've tried using Thunder client and postman as well as the browser. Same 200 status code. Here is trimmed version of the full code
const initServer = () => {
const app = express();
const port = 3000;
app.use(express.json());
app.use((req, res, next) => {
if (!process.env.UNIVERSAL_FS_PASSWORD) {
throw new Error(
"An environment variable UNIVERSAL_FS_PASSWORD is required to protect your files"
);
}
if (!req.headers.authorization) {
return res
.json({success: false, error: "An Authorization header is required"})
.status(401);
}
if (
!bycrypt.compareSync(
process.env.UNIVERSAL_FS_PASSWORD,
(req.headers.authorization as string).replace(/^Bearer\s/, "")
)
) {
return res
.json({success: false, error: "Unauthorized request"})
.status(401);
}
next();
});
app.use((req, res, next) => {
if (!req.query.method || req.query.method === "") {
return res.json({error: "A method is required"}).status(422);
}
if (req.method === "POST" && !req.body) {
return res
.json({error: "A body is required on post requests"})
.status(422);
}
next();
});
app.get("/:path", async (req, res) => {
switch (req.query.method) {
case "readFile":
let fileOptions: {
encoding?: null | undefined;
flag?: string | undefined;
} | null = null;
let fileBuffer: Buffer | null = null;
if (isJson(req.headers.options as string)) {
fileOptions = JSON.parse(req.headers.options as string);
}
try {
fileBuffer = fs.readFileSync(req.params.path, fileOptions);
return res.json({success: true, buffer: fileBuffer});
} catch (err: any) {
return res.json({success: false, error: err}).status(500);
}
// ...
default:
// This should never trigger because of the first check
return res.json({error: "Method not found"}).status(422);
}
});
//...
});
app.listen(port, () => {
console.info(`Listening on port ${port}`);
});
};
export default initServer;
I'm using rollup to bundle the code Nodemon to run. I'm using Node.js version v22.2.0 throughout the project.
You use the wrong order for method json
and status
, as Express suggests, use res.status(status).json(obj)
for sending a json result.
If you view the code for json
method, you can see this:
res.json = function json(obj) {
var val = obj;
// allow status / body
if (arguments.length === 2) {
// res.json(body, status) backwards compat
if (typeof arguments[1] === 'number') {
deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
this.statusCode = arguments[1];
} else {
deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');
this.statusCode = arguments[0];
val = arguments[1];
}
}
// settings
var app = this.app;
var escape = app.get('json escape')
var replacer = app.get('json replacer');
var spaces = app.get('json spaces');
var body = stringify(val, replacer, spaces, escape)
// content-type
if (!this.get('Content-Type')) {
this.set('Content-Type', 'application/json');
}
return this.send(body);
};
Watch out for the deprecate
statement. deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
For your case, you use json
before status
,which json object send back to client before status
method is called, at that point, statusCode
is not assigned, return 200 for default.
so you can change your code with the following 2 ways:
res.status(301).json(obj)
, which is recommended.res.json(301, obj)
or res.json(obj, 301)
, which is deprecated。