Реагировать - обрабатывать URI перенаправления для Spotify в Docker с Nginx - PullRequest
0 голосов
/ 21 марта 2019

У меня есть структура папок в моем приложении 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;

докер-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?

EDIT:

Я попробовал решение, предложенное в ответе ниже, сначала с localhost: 8888, а затем с localhost: 3000 (оба действительны как URL-адреса перенаправления в Spotify dev.)

Работает только с 8888, и даже так:

Приложение сбрасывает token в localStorage, но висит там со следующим предупреждением в браузере:

enter image description here

тогда, если я нажму на OK, и только если IF, он перенаправляет.

что не так?

1 Ответ

0 голосов
/ 21 марта 2019

Я думаю, вы должны перенаправить с 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 будет запускаться при загрузке компонента: подробнее здесь .

Вы также можете прочитать больше о OAuth2 здесь , вы используете поток Implict.

...