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.