React-使用Nginx在Docker中处理重定向URI到Spotify

时间:2019-03-20 22:44:02

标签: reactjs docker docker-compose spotify

我的docker应用中具有此文件夹结构:

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

这就是我从redirect uri呼叫client的方式:

  

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开发人员中作为重定向网址有效)

它仅适用于8888,甚至如此:

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

enter image description here

然后,如果我单击“确定”,并且仅单击IF,它将重定向。

怎么了?

1 个答案:

答案 0 :(得分:0)

我认为您应该从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上阅读更多信息,这是您使用的是隐式流程。