如何使用 Passport 本地身份验证为 Node.js 应用程序的 Axios 请求形成身份验证 Header?
How to Form Authentication Header for Axios Request to Node.js App Using Passport Local Authentication?
我有一个 node.js 应用程序,正在开发一个单独的单页应用程序(最终将转换为 Android 和 iOS 本机应用程序)。我正在 node.js 应用程序上设置 API 并且正在努力进行身份验证。 node.js 应用程序使用 passport-local-mongoose
进行身份验证,我将用户数据存储在 MongoDB 后端。对于 testing/dev,单页应用在 http://localhost:1234/
上是 运行。
我的端点看起来像:
exports.getDevicesAPI = async (req, res) => {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
const devices = await Device.find({ owner: req.user._id });
res.json(devices);
};
我可以 GET
这没问题,比如:
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
function getDevices() {
axios
.get(url)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
我想在服务器端添加authenticate = passport.authenticate('header', {session: false, failWithError: true});
来提供身份验证,但是下面给了我Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:7777/api/devices. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
:
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
const username = myUsername;
const password = myPassword;
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
},
Authorization: {
username,
password,
},
};
function authenticate() {
axios
.post(url, axiosConfig)
.then(function(response) {
console.log('Authenticated');
})
.catch(function(error) {
console.log('Error on Authentication');
});
}
路线(用于测试):
router.get('/api/devices', catchErrors(deviceController.getDevicesAPI));
router.post('/api/devices', catchErrors(deviceController.getDevicesAPI));
我错过了什么?
您遇到了 CORS(Cross-Origin 资源共享)限制的问题。阅读有关 CORS 的更多信息 here。
我相信您的这部分代码旨在处理 CORS:
exports.getDevicesAPI = async (req, res) => {
// ...
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
// ...
};
然而,这里的错误是这些 CORS headers 的设置与路由相关联,即不应该是 getDevicesAPI
路由。对于可能修改另一个来源的资源的请求(例如 POST 到 getDevicesAPI
路由),浏览器将在发送实际请求之前首先使用 OPTIONS
Http 方法发送预检请求,对预检请求的响应是预期设置必要的 CORS response-headers 的地方。您可以找到有关预检请求的解释 here。
我通常会在其他路由之上添加这样的中间件:
router.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', '*');
next();
});
我有一个 node.js 应用程序,正在开发一个单独的单页应用程序(最终将转换为 Android 和 iOS 本机应用程序)。我正在 node.js 应用程序上设置 API 并且正在努力进行身份验证。 node.js 应用程序使用 passport-local-mongoose
进行身份验证,我将用户数据存储在 MongoDB 后端。对于 testing/dev,单页应用在 http://localhost:1234/
上是 运行。
我的端点看起来像:
exports.getDevicesAPI = async (req, res) => {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
const devices = await Device.find({ owner: req.user._id });
res.json(devices);
};
我可以 GET
这没问题,比如:
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
function getDevices() {
axios
.get(url)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
我想在服务器端添加authenticate = passport.authenticate('header', {session: false, failWithError: true});
来提供身份验证,但是下面给了我Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:7777/api/devices. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)
:
const axios = require('axios');
const url = 'http://localhost:7777/api/devices';
const username = myUsername;
const password = myPassword;
const axiosConfig = {
headers: {
'Content-Type': 'application/json',
},
Authorization: {
username,
password,
},
};
function authenticate() {
axios
.post(url, axiosConfig)
.then(function(response) {
console.log('Authenticated');
})
.catch(function(error) {
console.log('Error on Authentication');
});
}
路线(用于测试):
router.get('/api/devices', catchErrors(deviceController.getDevicesAPI));
router.post('/api/devices', catchErrors(deviceController.getDevicesAPI));
我错过了什么?
您遇到了 CORS(Cross-Origin 资源共享)限制的问题。阅读有关 CORS 的更多信息 here。
我相信您的这部分代码旨在处理 CORS:
exports.getDevicesAPI = async (req, res) => {
// ...
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers: Authorization');
// ...
};
然而,这里的错误是这些 CORS headers 的设置与路由相关联,即不应该是 getDevicesAPI
路由。对于可能修改另一个来源的资源的请求(例如 POST 到 getDevicesAPI
路由),浏览器将在发送实际请求之前首先使用 OPTIONS
Http 方法发送预检请求,对预检请求的响应是预期设置必要的 CORS response-headers 的地方。您可以找到有关预检请求的解释 here。
我通常会在其他路由之上添加这样的中间件:
router.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', '*');
next();
});