OAuth पॉपअप क्रॉस-डोमेन सुरक्षा React.js


12

मैं कैसे पॉपअप ( window.open) का उपयोग करके रिएक्ट में OAuth को लागू करने में रुचि रखता हूं ।

उदाहरण के लिए मेरे पास है:

  1. mysite.com - यह वह जगह है जहां मैं पॉपअप खोलता हूं।
  2. passport.mysite.com/oauth/authorize - पॉप अप।

मुख्य सवाल यह है कि window.open(पॉपअप) के बीच संबंध कैसे बनाया जाए और window.opener(जैसा कि यह ज्ञात है। विंडोर क्रॉस-डोमेन सुरक्षा के कारण शून्य है इसलिए हम अब इसका उपयोग नहीं कर सकते हैं)।

Security window.openerहटा दिया जाता है जब भी आप एक अलग होस्ट (सुरक्षा कारणों से) पर नेविगेट करते हैं, तो इसके आसपास कोई रास्ता नहीं है। यदि संभव हो तो एक ही विकल्प एक फ्रेम में भुगतान करना चाहिए। शीर्ष दस्तावेज़ को एक ही होस्ट पर रहने की आवश्यकता है।

योजना:

यहां छवि विवरण दर्ज करें

संभव समाधान:

  1. यहांsetInterval वर्णित का उपयोग करके एक खुली हुई खिड़की की जांच करें
  2. क्रॉस-स्टोरेज का उपयोग करना (इसके लायक नहीं imho)।

तो 2019 में सबसे अच्छा अनुशंसित दृष्टिकोण क्या है?

प्रतिक्रिया के लिए रैपर - https://github.com/Ramshackle-Jamathon/react-oauth-pupup


2
2019 में, लोकलस्टोरेज सपोर्ट ज्यादा बेहतर है। मैं localStorage दृष्टिकोण (में वर्णित के साथ जाना होगा stackoverflow.com/questions/18625733/... ) के रूप में यह बहुत एक समाधान की तरह प्रतीत नहीं होता। माता-पिता की खिड़की को समय-समय पर बच्चे की खिड़की की स्थिति की जांच करने की आवश्यकता नहीं है। setIntervalलोकलस्टोरेज के लिए कमबैक के रूप में इस्तेमाल किया जा सकता है
खान

@KhanhTO, हाँ, मैं आपके बारे में पूरी तरह से सहमत हूं localStorage, लेकिन यह केवल उसी डोमेन के लिए काम करता है, इसलिए यह मेरी स्थिति में काम नहीं करता है
आर्थर

2
आपके द्वारा OAuth के साथ समाप्त करने के बाद, बच्चे की खिड़की को आपके डोमेन पर वापस भेज दिया गया है, आप अब उसी डोमेन में हैं जो माता
खान

@ खान्हो, हम्म, यह बहुत अच्छा विचार है! मुझे पता होना चाहिए था ..
आर्थर

1
यह बेहतर होगा कि यदि ब्राउज़र window.openerहमारे डोमेन पर वापस रीडायरेक्ट करने के बाद पुनर्स्थापित करता है , लेकिन ऐसा नहीं है
खान

जवाबों:


6

खान ने सुझाव दिया । लोकस्टस्टेज के साथ OAuth पॉपअप। प्रतिक्रिया-ओओथ-पॉपअप पर आधारित है ।

योजना:

यहां छवि विवरण दर्ज करें

कोड:

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

मैं एक बार ms- किनारे पर window.open/window.opener बग के साथ अपने oauth लॉगिन प्रवाह पर एक समस्या का सामना करता हूं

इस मुद्दे से पहले मेरा प्रवाह था

  • लॉगिन बटन पर एक पॉपअप खोलें क्लिक करें
  • सफल लॉगिन के बाद oauth ऐप मेरे डोमेन के पेज पर रीडायरेक्ट करता है
  • फिर मैं oauth प्रतिसाद के डेटा के साथ पॉपअप (window.opener.fn) से पैरेंट विंडो का एक फंक्शन कहता हूं और उसके बाद चाइल्ड पॉपअप विंडो बंद करता हूं

इस मुद्दे के बाद मेरा प्रवाह था

  • लॉगिन बटन पर एक पॉपअप खोलें क्लिक करें
  • मामले में एक समुच्चय बनाएँ (window.opener अपरिभाषित है)
  • सफल लॉगिन के बाद oauth ऐप मेरे डोमेन के पेज पर रीडायरेक्ट करता है
  • जांचें कि क्या window.opener उपलब्ध है, तो उपरोक्त प्रवाह और ClearInterval से # 3 करें
  • अगर window.opener उपलब्ध नहीं है, तो जब से मैं अपने डोमेन पृष्ठ पर हूं, मैं स्थानीयस्टोर सेट करने का प्रयास करता हूं और स्थानीय विंडो में से सेट को पढ़ने की कोशिश करता हूं, तो पैरेंट विंडो में इन्टरवल फ़ंक्शन को स्थानीय करें और फिर सेट करें।
  • (पश्चगामी अनुकूलता के लिए) यदि लोकलस्टोरेज उपलब्ध नहीं है, तो एक क्लाइंट एक्सपायरी डेटा को एक छोटी समाप्ति (5-10 सेकंड) के समय के साथ सेट करें और मूल विंडो में सेटइंटरवल फ़ंक्शन के अंदर कुकी (डॉक्यूमेंट.कॉकी) को पढ़ने का प्रयास करें। आगे बढ़ें।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.