OAuth popup cross-domain security React.js(OAuth 弹窗跨域安全 React.js)
问题描述
我对如何使用弹出窗口 (window.open
) 在 React 中实现 OAuth 很感兴趣.
例如我有:
mysite.com
— 这是我打开弹出窗口的地方.passport.mysite.com/oauth/authorize
— 弹出窗口.
主要问题是如何在 window.open
(弹出窗口)和 window.opener
之间创建连接(众所周知,window.opener 由于交叉而为空)域安全,因此我们不能再使用它了).
⇑ window.opener
每当您导航到不同的主机时都会被删除(出于安全原因),没有办法绕过它.如果可能的话,唯一的选择应该是在一个框架内付款.顶部文档需要保留在同一主机上.
方案:
可能的解决方案:
- 使用
代码:
oauth-popup.tsx:
import React, {PureComponent, ReactChild} from 'react'类型道具 = {宽度:数字,高度:数字,网址:字符串,标题:字符串,onClose: () =>任何,onCode: (params: any) =>任何,孩子?:ReactChild,}导出默认类 OauthPopup 扩展 PureComponent
;{静态 defaultProps = {onClose: () =>{},宽度:500,身高:500,网址:",标题: ""};外部窗口:任何;代码检查:任何;组件WillUnmount() {如果(this.externalWindow){this.externalWindow.close();}}createPopup = () =>{常量 {url, 标题, 宽度, 高度, onCode} = this.props;const left = window.screenX + (window.outerWidth - width)/2;常量顶部 = window.screenY + (window.outerHeight - 高度)/2.5;const windowFeatures = `toolbar=0,scrollbars=1,status=1,resizable=0,location=1,menuBar=0,width=${width},height=${height},top=${top},left=${左}`;this.externalWindow = window.open(网址,标题,窗口特点);常量 storageListener = () =>{尝试 {if (localStorage.getItem('code')) {onCode(localStorage.getItem('code'));this.externalWindow.close();window.removeEventListener('storage', storageListener);}} 抓住 (e) {window.removeEventListener('storage', storageListener);}}window.addEventListener('storage', storageListener);this.externalWindow.addEventListener('beforeunload', () => {this.props.onClose()}, 错误的);};使成为() {返回 (<div onClick={this.createPopup)}>{this.props.children}</div>);}} app.tsx
import React, {FC} from 'react'const onCode = async (): Promise<undefined>=>{尝试 {const res = await <your_fetch>} 抓住 (e) {控制台.错误(e);} 最后 {window.localStorage.removeItem('code');//从localStorage中删除代码}}const App: FC = () =>;(
I'm interested in how to implement OAuth in React using popup (
window.open
).For example I have:
mysite.com
— this is where I open the popup.passport.mysite.com/oauth/authorize
— popup.
The main question is how to create connection between
window.open
(popup) andwindow.opener
(as it's known the window.opener is null due to cross-domain security therefore we can't use it anymore).⇑
window.opener
is removed whenever you navigate to a different host (for security reasons), there is no way around it. The only option should be doing the payment in a frame if it is possible. The top document needs to stay on the same host.Scheme:
Possible solutions:
- Check an opened window using
setInterval
described here. Using cross-storage (not worth it imho ).
So what's the best recommended approach in 2019?
Wrapper for React - https://github.com/Ramshackle-Jamathon/react-oauth-popup
解决方案Suggested by Khanh TO. OAuth popup with localStorage. Based on react-oauth-popup.
Scheme:
Code:
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;
这篇关于OAuth 弹窗跨域安全 React.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:OAuth 弹窗跨域安全 React.js
基础教程推荐
- Chart.js 在线性图表上拖动点 2022-01-01
- 直接将值设置为滑块 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01