【问题标题】:React - handle Redirect URI to Spotify in Docker with NginxReact - 使用 Nginx 在 Docker 中处理重定向 URI 到 Spotify
【发布时间】:2019-08-11 18:21:57
【问题描述】:

我的 docker 应用中有这个文件夹结构:

nginx/
     dev.conf
client/
      src/
         Spotify.js

这就是我从client 调用redirect uri 的方式:

Spotify.js

  class SpotifyAuth extends Component {

  constructor () {
    super()

  this.handleRedirect = this.handleRedirect.bind(this)
  }

  getHashParams() {
    var hashParams = {};
    var e, r = /([^&;=]+)=?([^&;]*)/g,
        q = window.location.hash.substring(1);
    e = r.exec(q)
    while (e) {
       hashParams[e[1]] = decodeURIComponent(e[2]);
       e = r.exec(q);
    }
    return hashParams;
  }

  handleRedirect = (e) => {
    axios.get("http://localhost:8888" )
    .then(response => response.json())
    .then(data => console.log(data))
    .catch((err) => { console.log(err); });
    //e.preventDefault();
  }

  render () {
    return (
      <div className='button__container'>
        <button className='button' onClick={this.handleRedirect}
        ><strong>CONNECT YOUR SPOTIFY ACCOUNT</strong>
        </button>
      </div>
    )
  }
}
export default SpotifyAuth;

docker-compose-dev.yml

 nginx:
    build:
      context: ./services/nginx
      dockerfile: Dockerfile-dev
    restart: always
    ports:
      - 80:80
      - 8888:8888

    depends_on:
      - web
      - client

  client:
    build:
      context: ./services/client
      dockerfile: Dockerfile-dev
    volumes:
      - './services/client:/usr/src/app'
      - '/usr/src/app/node_modules'
    ports:
      - 3007:3000
    environment:
      - NODE_ENV=development
      - REACT_APP_WEB_SERVICE_URL=${REACT_APP_WEB_SERVICE_URL}
    depends_on:
      - web

nginx/dev.conf

server {

  listen 80;

  location / {
    proxy_pass        http://client:3000;
    proxy_redirect    default;
    proxy_set_header  Upgrade $http_upgrade;
    proxy_set_header  Connection "upgrade";
    proxy_set_header  Host $host;
    proxy_set_header  X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Host $server_name;
  }
}

如何正确授权并处理来自Spotify.js的令牌?

编辑:

我已经尝试了以下答案提出的解决方案,首先使用 localhost:8888,然后使用 localhost:3000(两者都在 Spotify 开发中作为重定向 URL 有效)

它只适用于 8888,即便如此:

应用程序将token 转储到localStorage,但挂起并在浏览器上显示以下警报:

然后,如果我点击 OK,并且只有 IF,它会重定向。

怎么了?

【问题讨论】:

  • 您是否有理由从 localhost 传递到 localhost:8888,以便可以进一步将用户重定向到 spotify?
  • for localhost 我有 nginx 在位置 client:3000 进行监听,我将其用于另一个注册和登录流程(用于应用程序 REST API 本身,具有自己的令牌)。不过,我不知道这是否是最佳做法。
  • 您可以更改在 Spotify 注册的 oauth 客户端的 redirect_uri 吗?
  • 当然。如果您的解决方案需要这个,我会试一试。

标签: reactjs docker docker-compose spotify


【解决方案1】:

我认为你应该从localhost 直接重定向到spotify.com,而忽略localhost:8888

我已将localhost:8888 上的代码移到 React 组件中,以便在您被重定向回来时处理重定向和访问令牌的保存。

const stateKey = 'spotify_auth_state';
const client_id = 'myid'; // Your client id
const redirect_uri = 'http://localhost:3000'; // Your redirect uri
const scope =
  'user-read-private user-read-email user-read-playback-state playlist-modify-public playlist-modify-private';

function generateRandomString(length) {
  let text = '';
  const possible =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

  for (let i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  return text;
}

class SpotifyAuth extends React.Component {
  getHashParams() {
    const hashParams = {};
    const r = /([^&;=]+)=?([^&;]*)/g;
    const q = window.location.hash.substring(1);
    let e = r.exec(q);
    while (e) {
      hashParams[e[1]] = decodeURIComponent(e[2]);
      e = r.exec(q);
    }
    return hashParams;
  }

  componentDidMount() {
    const params = this.getHashParams();

    const access_token = params.access_token;
    const state = params.state;
    const storedState = localStorage.getItem(stateKey);
    localStorage.setItem('spotify_access_token', access_token);
    localStorage.getItem('spotify_access_token');

    if (access_token && (state == null || state !== storedState)) {
      alert('There was an error during the authentication');
    } else {
      localStorage.removeItem(stateKey);
    }

    // DO STUFF WITH ACCESS TOKEN HERE
  }

  handleRedirect() {
    const state = generateRandomString(16);
    localStorage.setItem(stateKey, state);

    let url = 'https://accounts.spotify.com/authorize';
    url += '?response_type=token';
    url += '&client_id=' + encodeURIComponent(client_id);
    url += '&scope=' + encodeURIComponent(scope);
    url += '&redirect_uri=' + encodeURIComponent(redirect_uri);
    url += '&state=' + encodeURIComponent(state);

    window.location = url;
  }

  render() {
    return (
      <div className="button__container">
        <button className="button" onClick={this.handleRedirect}>
          <strong>CONNECT YOUR SPOTIFY ACCOUNT</strong>
        </button>
      </div>
    );
  }
}

componentDidMount 函数将在组件加载时运行:see more here

您还可以在OAuth2 here 上阅读更多信息,您正在使用隐式流程。

【讨论】:

  • 只是http://localhost/as URI,没有任何端口,会引发错误“这是身份验证错误”。不过,我在控制台获得了令牌,所以我们已经完成了一半......
  • 应用程序也没有重定向回本地主机。
  • 忘了说您需要将 Spotify OAuth 客户端上的 redirect_uri 更新为 http://localhost/。我无法复制警报。
  • 你的意思是用 spotify api 更新?做到了。添加http://localhost/,保存它,这个URI会抛出一个错误:INVALID_CLIENT,无效的URI,如果我将重定向改回http://localhost:8888,它会得到令牌,但在授权时提醒我一个未定义的错误
  • 我们是不是可能错过了ajax 电话,fecth()axios.get()?在handleDirect 中调用uri?因为 auth-server 监听端口 8888,但我们没有将端口传递给监听的服务。记住我们在一个 docker 容器中。
猜你喜欢
  • 2019-08-05
  • 1970-01-01
  • 2020-07-17
  • 2015-03-12
  • 2014-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 2016-11-03
相关资源
最近更新 更多