如何从外部的Node/Express服务器重定向页面?

19 浏览
0 Comments

如何从外部的Node/Express服务器重定向页面?

我有一个React/Node/Express的Web应用正在运行,有两个独立的服务器。React运行在localhost:8080,代理API请求到运行在localhost:3000的node服务器上。这将是我在生产环境中的设置,所以如果可能的话,我希望保持这个结构不变。

我遇到的问题是,我的API的一部分需要将用户重定向到一个页面,从Spotify API中获取一个令牌,然后在成功验证后重定向回我的正确页面。

API调用代理是这样做的:

const axios = require('axios');
const axiosInstance = axios.create({
    baseURL: process.env.NODE === 'production' ? '' : 'http://localhost:3000'
});
module.exports = axiosInstance;

到目前为止,这个方法很好用,因为我可以完全分离我的React和Node服务器。

正如我上面提到的,我需要通过后端的API调用将我的React前端重定向到一个不同的页面(Spotify认证)来验证用户,然后在用户允许或拒绝访问他们的Spotify账户后,Spotify会将用户重定向回我的网站。

在我的前端 - localhost:8080,用户点击一个按钮,调用这个函数。

authenticate = () => {
    axios.get('/login')
        .then(data => console.log(data));
}

这将调用localhost:3000上的这个端点。

router.get('/', (req, res) => {
    let scopes = 'user-read-private user-read-email';
    let client = process.env.SPOTIFY_CLIENT;
    let redirect = 'http://localhost:3000/login/redirect';
    res.redirect(`https://accounts.spotify.com/authorize?response_type=code'
                &client_id=${client}${scopes ? `&scope=${encodeURIComponent(scopes)}` : ''}
                &redirect_uri=${encodeURIComponent(redirect)}&state=${state}`);
});

当我在前端点击登录按钮时,我得到这个响应,我相信这是来自Spotify的,因为我可以成功地对我的API中的其他端点进行跨域请求。

Failed to load... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

然而,当我手动导航到localhost:3000/login时,重定向起作用,我被发送到Spotify认证页面。

此外,我尝试重定向我的前端到任何URL,但它不起作用。

所以我的问题是,如何在不提供静态前端内容的服务器上通过API调用将我的前端重定向?

0
0 Comments

问题的原因是,axios.get('/login')是一个向服务器发送的AJAX请求,服务器告诉AJAX请求要重定向到Spotify,但是Spotify没有注册你的前端服务器,所以你得到了CORS错误,因为你的请求是在前端服务器URL上发起的。

你的AJAX请求会遵循给出的重定向,而不是尝试在http://localhost:3000上加载你的浏览器,然后再重定向到Spotify的授权页面。

现在,你可以这样做:

authenticate = () => {
    window.location.href = "http://localhost:3000"
}

这将使你的前端应用程序访问API服务器的URL,并立即跟随重定向到Spotify,然后你可以进行授权并被重定向回你的API服务器,然后API服务器可以重定向回你的前端应用程序。

实际上,这有点过分了,因为假设你的React应用程序和Node应用程序在开发之外看起来像是在同一个域上运行,因为你使用的是相对URL。如果你使用的是create-react-app,你应该按照他们的说明通过这个或者通过这个手动配置代理。

简而言之,你需要调整代理的配置方式,或者改为直接访问/login而不是进行AJAX请求。

这个解决方法有效。我曾考虑过在package.json中指定代理,但决定尝试这个方法(我没有使用CRA)。我确实理解你的观点,这有点过分。我主要设置这个项目是因为我想要使用任何语言编写我的后端,并进行一些关于查询不同后端的研究,这就是我找到有关设置axios基本URL的方法。

0