OAuth açılır alanlar arası güvenlik React.js


12

Popup ( window.open) kullanarak React OAuth uygulamak ile ilgileniyorum .

Örneğin:

  1. mysite.com - burası pop-up'ı açtığım yer.
  2. passport.mysite.com/oauth/authorize - aniden belirmek.

Ana soru, window.open(popup) ve window.opener( nasıl bilindiği gibi, etki alanları arası güvenlik nedeniyle window.opener'ın boş olduğu için ) nasıl bağlantı oluşturulacağıdır , bu yüzden artık kullanamayız.

window.openerfarklı bir ana bilgisayara her gittiğinizde (güvenlik nedeniyle) kaldırılır, etrafında bir yol yoktur. Mümkünse tek seçenek ödemeyi bir çerçevede yapmak olmalıdır. Üstteki belgenin aynı ana bilgisayarda kalması gerekir.

Şema:

resim açıklamasını buraya girin

Olası çözümler:

  1. BuradasetInterval açıklanan şekliyle açık bir pencereyi kontrol edin .
  2. Çapraz depolama kullanma (buna değmez).

2019'da en iyi önerilen yaklaşım nedir?

React için Sarıcı - https://github.com/Ramshackle-Jamathon/react-oauth-popup


2
2019'da localStorage desteği çok daha iyi. Çok geçici bir çözüm gibi görünmüyor gibi localStorage yaklaşım ( stackoverflow.com/questions/18625733/… 'de tarif ) ile gitmek istiyorum. Üst pencerenin alt pencere durumunu düzenli aralıklarla kontrol etmesi gerekmez. setIntervallocalStorage
Khanh TO

@KhanhTO, evet, sizinle tamamen aynı fikirdeyim localStorage, ancak yalnızca aynı etki alanı için çalışıyor, bu yüzden benim durumumda çalışmıyor
Arthur

2
OAuth ile işiniz bittiğinde, alt pencere alan adınıza geri yönlendirilir, artık ana alan
Khanh TO

@KhanhTO, hm, bu harika bir fikir!
Arthur

1
Tarayıcı window.opener, alanımıza geri yönlendirdikten sonra geri yüklerse daha iyi olurdu , ancak durum böyle değil
Khanh TO

Yanıtlar:


6

Khanh TO tarafından önerildi . OAuth localStorage ile açılır. Göre reaksiyona-oauth-açılır .

Şema:

resim açıklamasını buraya girin

Kod:

oauth-popup.tsx:

import React, {PureComponent, ReactChild} from 'react'

type Props = {
  width: number,
  height: number,
  url: string,
  title: string,
  onClose: () => any,
  onCode: (params: any) => any,
  children?: ReactChild,
}

export default class OauthPopup extends PureComponent<Props> {

  static defaultProps = {
    onClose: () => {},
    width: 500,
    height: 500,
    url: "",
    title: ""
  };

  externalWindow: any;
  codeCheck: any;

  componentWillUnmount() {
    if (this.externalWindow) {
      this.externalWindow.close();
    }
  }

  createPopup = () => {
    const {url, title, width, height, onCode} = this.props;
    const left = window.screenX + (window.outerWidth - width) / 2;
    const top = window.screenY + (window.outerHeight - height) / 2.5;

    const windowFeatures = `toolbar=0,scrollbars=1,status=1,resizable=0,location=1,menuBar=0,width=${width},height=${height},top=${top},left=${left}`;

    this.externalWindow = window.open(
        url,
        title,
        windowFeatures
    );

    const storageListener = () => {
      try {
        if (localStorage.getItem('code')) {
          onCode(localStorage.getItem('code'));
          this.externalWindow.close();
          window.removeEventListener('storage', storageListener);
        }
      } catch (e) {
        window.removeEventListener('storage', storageListener);
      }
    }

    window.addEventListener('storage', storageListener);

    this.externalWindow.addEventListener('beforeunload', () => {
      this.props.onClose()
    }, false);
  };

  render() {
    return (
      <div onClick={this.createPopup)}>
        {this.props.children}
      </div>
    );
  }
}

app.tsx

import React, {FC} from 'react'

const onCode = async (): Promise<undefined> => {
  try {
    const res = await <your_fetch>
  } catch (e) {
    console.error(e);
  } finally {
    window.localStorage.removeItem('code'); //remove code from localStorage
  }
}

const App: FC = () => (
  <OAuthPopup
    url={<your_url>}
    onCode={onCode}
    onClose={() => console.log('closed')}
    title="<your_title>">
    <button type="button">Enter</button>
  </OAuthPopup>
);

export default App;

3

Bir keresinde ms- edge'de window.open/window.opener hatasıyla oauth giriş akışımda bir sorunla karşılaştım

Bu sayıdan önceki akışım şuydu:

  • Giriş düğmesinde bir açılır pencere tıklayın
  • Başarılı bir şekilde giriş yaptıktan sonra oauth uygulaması alanımın sayfasına yönlendiriyor
  • Daha sonra oauth yanıtı ve üst pencereden gelen verilerle açılır pencerede (window.opener.fn) ile ana pencerenin bir işlevini çağırıyorum ve sonra alt açılır pencereyi kapatıyorum

Bu sayıdan sonraki akışım

  • Giriş düğmesinde bir açılır pencere tıklayın
  • Durumda bir setinterval oluşturun (window.opener tanımsızsa)
  • Başarılı bir şekilde giriş yaptıktan sonra oauth uygulaması alanımın sayfasına yönlendiriyor
  • Window.opener'ın kullanılabilir olup olmadığını kontrol edin, ardından yukarıdaki akıştan # 3 yapın ve clearInterval
  • Window.opener kullanılamıyorsa, etki alanları sayfamda olduğumdan beri localstorage'ı ayarlamaya çalışıyorum ve localstorage'ı üst pencerede setInterval işlevinin içinden okumaya çalışıyorum, ardından localstorage'ı ve setInterval ve ilerlemeye çalışın.
  • (geriye dönük uyumluluk için) Yerel depolama alanı da mevcut değilse, kısa bir süre (5-10 sn) süreli veriler içeren bir istemci tarafı çerezi ayarlayın ve üst pencerede setInterval işlevinin içindeki çerezi (document.cookie) okumaya çalışın ve ilerlemek.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.