首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Oauth 2弹出窗口,角度为2

Oauth 2弹出窗口,角度为2
EN

Stack Overflow用户
提问于 2016-01-06 00:14:32
回答 4查看 11K关注 0票数 6

我正在升级/重写一个现有的angular应用程序来使用angular2。我的问题是,我想在一个新的弹出窗口中打开一个OAuth流,一旦OAuth流完成,使用window.postMessage向angular 2应用程序传回OAuth流成功的消息。

目前我在angular 2服务中拥有的是

代码语言:javascript
复制
export class ApiService { 
    constructor(private _loggedInService: LoggedInService) {
        window.addEventListener('message', this.onPostMessage, false);
     }

    startOAuthFlow() {
       var options = 'left=100,top=10,width=400,height=500';
       window.open('http://site/connect-auth', , options);
    }

    onPostMessage(event) {
      if(event.data.status === "200") {
          // Use an EventEmitter to notify the other components that user logged in
          this._loggedInService.Stream.emit(null);
      }
    }

}

此模板在OAuth流的末尾加载

代码语言:javascript
复制
<html>
  <head>
    <title>OAuth callback</title>
    <script>
      var POST_ORIGIN_URI = 'localhost:8000';
      var message = {"status": "200", "jwt":"2"};
      window.opener.postMessage(message, POST_ORIGIN_URI);
      window.close();
    </script>
  </head>
</html>

像这样使用window.addEventListener似乎完全破坏了angular 2应用程序,取消了对this的引用。

所以我的问题是,我可以使用window.addEventListener,还是不应该使用postMessage与angular2应用程序通信?

**完成angular2 noob,如有任何帮助,不胜感激

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-01-06 22:56:43

所以通过一点调查就找到了问题所在。我在解除this的引用。这个github wiki帮助我更好地理解了它。

为了解决我的问题需要做几件事。首先,我创建了一个封装添加eventListener的服务

代码语言:javascript
复制
import {BrowserDomAdapter} from 'angular2/platform/browser';

export class PostMessageService {
   dom = new BrowserDomAdapter();
   addPostMessageListener(fn: EventListener): void {
     this.dom.getGlobalEventTarget('window').addEventListener('message', fn,false)
   }
}

然后使用这个addPostMessageListener,我可以在我的其他服务中附加一个函数来触发

代码语言:javascript
复制
constructor(public _postMessageService: PostMessageService,
    public _router: Router) {
    // Set up a Post Message Listener
    this._postMessageService.addPostMessageListener((event) => 
          this.onPostMessage(event)); // This is the important as it means I keep the reference to this

}

然后它就会按照我所期望的那样工作,保持对这个的引用

票数 3
EN

Stack Overflow用户

发布于 2016-01-06 07:13:23

我在Github上有一个完整的Angular2 OAuth2框架应用程序,你可以参考。

它使用OAuth2隐式授权的Auth服务,然后使用窗口服务创建弹出窗口。然后,它在该窗口中监视URL上的访问令牌。

您可以访问demo OAuth2 Angular code (with Webpack) here

下面是来自Auth服务的登录例程,它可以让您了解发生了什么,而不必查看整个项目。我在这里为你添加了一些额外的评论。

代码语言:javascript
复制
public doLogin() {
    var loopCount = this.loopCount;
    this.windowHandle = this.windows.createWindow(this.oAuthTokenUrl, 'OAuth2 Login');

    this.intervalId = setInterval(() => {
        if (loopCount-- < 0) { // if we get below 0, it's a timeout and we close the window
            clearInterval(this.intervalId);
            this.emitAuthStatus(false);
            this.windowHandle.close();
        } else { // otherwise we check the URL of the window
            var href:string;
            try {
                href = this.windowHandle.location.href;
            } catch (e) {
                //console.log('Error:', e);
            }
            if (href != null) { // if the URL is not null
                var re = /access_token=(.*)/;
                var found = href.match(re);
                if (found) { // and if the URL has an access token then process the URL for access token and expiration time
                    console.log("Callback URL:", href);
                    clearInterval(this.intervalId);
                    var parsed = this.parse(href.substr(this.oAuthCallbackUrl.length + 1));
                    var expiresSeconds = Number(parsed.expires_in) || 1800;

                    this.token = parsed.access_token;
                    if (this.token) {
                        this.authenticated = true;
                    }

                    this.startExpiresTimer(expiresSeconds);
                    this.expires = new Date();
                    this.expires = this.expires.setSeconds(this.expires.getSeconds() + expiresSeconds);

                    this.windowHandle.close();
                    this.emitAuthStatus(true);
                    this.fetchUserInfo();
                }
            }
        }
    }, this.intervalLength);
}

如果您有任何问题或问题,请随时询问应用程序的启动和运行。

票数 6
EN

Stack Overflow用户

发布于 2016-01-06 00:21:11

我认为这是Angular2的方式:

(Dart代码,但TS应非常相似)

代码语言:javascript
复制
@Injectable()
class SomeService {
  DomAdapter dom;
  SomeService(this.dom) {
    dom.getGlobalEventTarget('window').addEventListener("message", fn, false);
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34616248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档