【问题标题】:How can I redirect a page from an external Node/Express server如何从外部 Node/Express 服务器重定向页面
【发布时间】:2018-03-26 03:20:10
【问题描述】:

我有一个 React/Node/Express Web 应用程序,并在两个单独的服务器上运行。 React 在localhost:8080 上运行,并将API 请求代理到我在localhost:3000 上运行的节点服务器。这将是我的生产设置,所以如果可能的话,我想保持这个结构完好无损。

我遇到的问题是我的 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 调用重定向我的前端?

【问题讨论】:

  • 你试过使用任何 cors 包吗?喜欢npmjs.com/package/cors ?
  • @GavinThomas 是的。我的服务器上安装了 CORS。我应该澄清一下,这个回复来自 Spotify,而不是我的 API。我能够成功地向我的 API 发出请求。
  • 并且您使用您拥有令牌的 spotify 帐户注册了您的重定向 URL? github.com/spotify/web-api-auth-examples ?
  • @GavinThomas 是的。正如我所说,当我直接导航到 API url 时它可以正常工作。
  • 由于直接请求有效,请尝试向 Spotify 发出新请求并返回响应,而不是重定向原始 8080 请求。 Spotify 可能会检测到请求 URL(应该读取 8080)而不是此处指定的 3000 ==> redirect_uri=${encodeURIComponent(redirect)}。如果对该 API 的所有请求肯定都是代理,那么将查询中的端口更改为 8080

标签: node.js reactjs express


【解决方案1】:

这不起作用的原因是因为您的 axios.get('/login') 是对您的服务器的 AJAX 请求,然后您的服务器告诉 AJAX 请求重定向到 Spotify,但 Spotify 没有注册您的前端服务器因此您会收到 CORS 错误,因为您的请求是在前端服务器 URL 上发起的。

Your AJAX request is following that redirect that was given,不要尝试在http://localhost:3000 上加载您的浏览器,这会将其重定向到 Spotify 授权页面。

现在,而不是做:

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

你可以这样做:

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

这将引导您的前端应用程序访问您的 API 服务器的 URL 并立即按照重定向到 Spotify,然后您可以授权并将其重定向到您的 API 服务器返回,然后可以重定向回您的前端应用程序。

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

tl;博士您需要修改您的代理的配置方式从在那里执行 AJAX 请求更改为实际直接转到 /login(不执行 AJAX 请求)。

【讨论】:

  • 这行得通。我曾考虑在package.json 中指定一个代理,但决定试一试(我没有使用 CRA)。我确实明白你的观点,这有点矫枉过正。我主要建立这个项目是因为我想要灵活地用任何语言编写我的后端。我之前做过一些关于查询不同后端的研究,这就是我发现设置 axios 基本 url 的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多