web-dev-qa-db-ja.com

ログインしていないユーザーをiron-routerでリダイレクト...もう一度

ユーザーがログインしていない場合にユーザーをログインページにリダイレクトするという一般的なニーズと戦っています(Windows7のMeteorv0.8.0)。

Stackoverflowについても同様の質問がいくつかありますが、私には答えがないようです。

動作しない#1:render()

ドキュメント から:

_onBeforeAction: function () {
  if (!Meteor.user()) {
    // render the login template but keep the url in the browser the same
    this.render('login');

    // stop the rest of the before hooks and the action function 
    this.stop();
  }
},
_

ここで2つの問題:

1-ドキュメントが古くなっています。 this.stop()関数はもうありません。述べたように ここ 、コードは次のようになります:

_onBeforeAction: function (pause) {
  if (!Meteor.user()) {
    // render the login template but keep the url in the browser the same
    this.render('login');

    // stop the rest of the before hooks and the action function 
    pause();
  }
},
_

2-これは、ルートにlayoutTemplateがない場合にのみ機能します。存在する場合、loginテンプレートはlayoutTemplateの_{{>yield}}_にレンダリングされます。これは通常、ログインページに必要なものではありません。

機能しない#2:Router.go()またはthis.redirect()

ログインページのルートを定義するのは自然な方法のように思えます。その後、次のことができます。

_Router.onBeforeAction(function(pause) {
    if (!Meteor.user()) {
        pause();
        Router.go('\login');
    }
}, {except: ['login']});
_

または:

_Router.onBeforeAction(function() {
    if (!Meteor.user())
        this.redirect('\login');
}, {except: ['login']});
_

しかし、奇妙なことに、元のルート(リダイレクト前)にlayoutTemplateがある場合は、まだ問題があります。_/login_テンプレートは_{{yield}}_内にレンダリングされます。これも通常必要なものではありません(_/login_テンプレートにはlayoutTemplateが定義されていないため、間違いなく期待したものではありません)。

私はこれを部分的に解決する方法を見つけました:

_Router.onBeforeAction(function() {
    if (!Meteor.user()) {
        var that = this;
        setTimeout(function() { that.redirect('\login'); }, 0);
    }
}, {except: ['login']});
_

_/login_テンプレートが表示される前に、元のルートのlayoutTemplateが一時的に点滅することを除いて、_/login_テンプレートはクリーンページとしてレンダリングされます。

これと同じ問題がありますか?

20
steph643

OK、ルートのレンダリング関数はテンプレートを現在のレイアウトにレンダリングするだけのようです。テンプレートを別のレイアウトにレンダリングするには、this.setLayout('templateName')を呼び出す必要があります。 1つの注意点は、ログイン後にレイアウトを元に戻す必要があることです。

_onBeforeAction: function(pause) {
    var routeName = this.route.name;

    if (_.include(['login'], routeName))
        return;

    if (! Meteor.userId()) {
        this.setLayout("newLayout");
        this.render('login');

        //if you have named yields it the login form
        this.render('loginForm', {to:"formRegion"});

        //and finally call the pause() to prevent further actions from running
        pause();
    }else{
        this.setLayout(this.lookupLayoutTemplate());
    }
}
_

ログインテンプレートがthis.setLayout('login')を呼び出すことで必要なすべての場合、レイアウトとしてログインテンプレートをレンダリングすることもできます。

9
Kelly Copley

レイアウトテンプレートにifまたはunlessテンプレートヘルパーを配置できます。

{{#unless currentUser}}
  {{> loginPage}}
 {{else}}
  {{> yield}}
{{/unless}}
20
LakeEffect

これは、waitOnでのサブスクリプションの待機と関係があるようです。

以下は私のためにレイアウトレンダリング問題を解決します:

Router.onBeforeAction(function() {
    if (!Meteor.user() && this.ready())
        return this.redirect('/login');
}, {except: ['login']}); 
3
Eelco

render()からonBeforeAction()の結果を返す必要があります。

_onBeforeAction: function () {

  if (_.include(['login'], this.route.name)){
    return;
  }

  if (!Meteor.userId()) {

    return this.render('login');

  }
}
_

また、Meteor.user()Meteor.userId()に変更したことに注意してください。これにより、現在のユーザーのドキュメントが変更されるたびにフックが再実行されなくなります。

0
Kelly Copley

Meteor 0.8.3で私は動作します:

Router.onBeforeAction(function () { 
  if (_.include(['formLogin'], this.route.name)){
    return;
  }

  if (!Meteor.userId()) {
    this.redirect('formLogin');
    return;
  }

});
0
pwldp