使用铁路由器重定向未登录的用户...再次

时间:2014-05-02 13:38:46

标签: meteor iron-router

我正在努力解决如果用户未登录而将用户重定向到登录页面的常见需求(Windows 7上的Meteor v0.8.0)。

stackoverflow上有几个类似的问题,但似乎没有答案对我有用。

无法正常工作#1:render()

来自the documentation

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();
  }
},

这里有两个问题:

1-文档已过时。没有this.stop()功能了。如上所述here,代码应为:

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模板会在{{>yield}}的{​​{1}}中呈现。这通常不是您想要的登录页面。

无效#2:Router.go()或this.redirect()

为登录页面定义路线听起来像是自然的方式。然后你可以这样做:

layoutTemplate

或者:

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模板之前短暂闪烁。

你有同样的问题吗?

5 个答案:

答案 0 :(得分:20)

您可以在布局模板中放置if或unless模板助手。

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

答案 1 :(得分:9)

好的,所以似乎路由上的渲染功能只会将模板渲染到当前布局中。要将模板渲染到不同的布局,您必须调用this.setLayout('templateName')。一个警告似乎是你需要在登录后重新设置布局。

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')

,您也可以将登录模板呈现为布局

答案 2 :(得分:3)

看起来这与等待waitOn中的订阅有关。

以下解决了我的布局渲染问题:

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

答案 3 :(得分:0)

您只需要从render()

返回onBeforeAction()的结果
onBeforeAction: function () {

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

  if (!Meteor.userId()) {

    return this.render('login');

  }
}

另请注意,我已将Meteor.user()更改为Meteor.userId()。这样可以防止每当当前用户记录文件时重新运行挂钩。

答案 4 :(得分:0)

On Meteor 0.8.3 for me works:

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

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

});