javascript - 将 fetch 与 Passport 一起使用会得到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头。”
问题描述
我试图在我的网站上放置一个按钮,让用户授权访问他的 YouTube 帐户。我正在使用 Passport 进行身份验证。我的代码使用 fetch 发送请求。当我点击按钮时,我得到:
访问 'https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fgooglecb&scope=https%3A%2F%2Fwww.googleapis .com%2Fauth%2Fyoutube&client_id=...'(从 'http://localhost:3000/google' 重定向)来自 'http://localhost:3000' 已被 CORS 策略阻止:对预检请求的响应没有' t 通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
如果我对 /google 使用 href 它可以工作。
应用程序.js:
const appConfig = require('./config.js');
const cors = require('cors')
const express = require('express');
const passport = require('passport');
const path = require('path');
const YoutubeV3Strategy = require('passport-youtube-v3').Strategy;
const index = require('./routes/index');
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
passport.use(new YoutubeV3Strategy({
clientID: appConfig.youtube.id,
clientSecret: appConfig.youtube.secret,
callbackURL: 'http://localhost:3000/googlecb',
scope: ['https://www.googleapis.com/auth/youtube'],
},
function (accessToken, refreshToken, profile, cb) {
const user = {
accessToken: accessToken,
refreshToken: refreshToken,
profile: profile,
};
return cb(null, user);
}));
passport.serializeUser((user, cb) => {
cb(null, user);
});
passport.deserializeUser((obj, cb) => {
cb(null, obj);
});
app.use('/', index);
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js:
const express = require('express');
const passport = require('passport');
const router = express.Router();
router.get('/', function(req, res, next) {
res.render('index');
});
router.get('/google', async (req, res) => {
passport.authenticate('youtube')(req, res, () => res.send('ok'));
});
router.get('/googlecb', passport.authenticate('youtube'), async (req, res) => {
const name = req.user.profile.displayName;
console.log('googlecb name: ' + name);
return res.send(req.user);
});
module.exports = router;
索引.ejs:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p><button id="auth" onclick="go()">Authorize</button><p>
<p><a href="/google">Authorize</a><p>
<script>
async function go() {
console.log('go');
await fetch('/google',
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
},
)
.then(response => {
console.log('response');
return response.json();
})
.then(data => {
console.log('data');
});
}
</script>
</body>
</html>
解决方案
好的,这是 Passport 的一个未解决问题:
https://github.com/jaredhanson/passport/issues/582#issuecomment-506283986
我应该使用 href 而不是获取。
可能的重复
推荐阅读
- css - gcc 同时编译和链接目标文件和源文件
- angular - Angular Material Stepper 图标未按应显示的方式显示 - 气泡、线条和当前阶段
- python-3.x - ValueError:两个形状中的维度 0 必须相等,但使用 tensorflow 2.2 时为 0 和 512
- azure - 到 API-M 的 Azure 前门路由返回“DNSNameNotResolved”错误信息
- java - 我怎样才能得到超类对象
- image - 高级图像过滤器
- docker - 删除 docker 容器后如何保留日志文件?
- javascript - 将 Stryker JS 与 SVN 存储库一起使用
- valgrind - 在 fdopen 之后关闭 popen 流是否有任何问题
- c++ - 如何在同一个图表中绘制多个线系列?