没有密码的流星帐户

Meteor Accounts without Passwords

本文关键字:流星 密码      更新时间:2023-09-26

我想在Meteor中创建一个帐户系统,用户无法创建自己的帐户,并且没有密码。从本质上讲,用户可以通过给定用户帐户名称(在我的例子中是整数字符串)来登录。我尝试使用 accounts-pasword 模块并对其进行修改,但对我来说,我该怎么做似乎并不明显。

现在,我有一个流星方法createPlayer

createPlayer: function() {
    var id = Math.floor(Math.random() * 10000000).toString();
    Accounts.createUser({ username: id, password: "test" });
    return id;
}

我在服务器重新启动时调用它:

for (var i = 0; i < numberOfUsers; i++) {
        Meteor.call("createPlayer");
    }

这里的缺点是(1)用户必须在默认密码"test"中输入密码字段,以及(2)除了我已经创建的帐户之外,仍然有一个按钮供用户创建新帐户。

编辑:该解决方案必须使我能够仅发布与登录用户相关的数据。例如,使用帐户密码,我可以在发布中使用this.userId来始终拥有最新的任务列表:

Meteor.publish("tasks", function () {
        var user = Meteor.users.findOne(this.userId);
        if (user && user.admin) {
            return Tasks.find({});
        }
        return Tasks.find({ user: this.userId });
    });

任何帮助,不胜感激。

如果您不想使用密码,则不需要accounts-password或任何包,只需创建一个集合并将用户插入该集合即可。如果使用simple-schema则可以为集合定义架构

Users = new Mongo.Collection('userInfo'); //I am using userInfo because, users is used by accounts package
Users_Schema = new SimpleSchema({   
    username: {
        type: String,
        optional: false
    },
    firstName: {
        type: String,
        optional: false
    },
    lastName: {
        type: String,
        optional: false 
    },
    age: {
        type: Number,
        optional: false
    },
    //.. other details that you need.
});
Users.attachSchema(Users_Schema);

然后,您可以插入一个新用户,而不是Accounts.createUser,您可以检查username是否已经存在并相应地抛出错误。

Users.insert({
    username: "someUniqueUsername",
    firstName: "userFirstName",
    lastName: "userLastName",
    age: 20
});

deny规则添加到此Users集合,以便用户无法直接从客户端添加或删除用户。

Users.deny({
    insert: function () {
        return true;
    },
    update: function () {
        return true;
    },
    remove: function () {
        return true;
    }
});

更新

据我所知,使用accounts软件包无法在没有密码的情况下实现登录。要澄清您在评论中的第二点,请参阅以下内容。

对于登录表单 HTML,请为用户名和登录按钮创建一个输入字段,

<template name="loginForm">
    <label for="username">Username:</label>
    <input id="username" type="text" /><br/>
    <input id="btnLogin" type="button" value="Login" />
</template>

在登录 JS 中,为登录按钮编写事件侦听器。按下登录按钮时,获取userId并调用检查用户是否可用的服务器方法。如果结果为 true,则数据库中有一个用户,因此设置一个会话变量。

Template.loginForm.events({
    'click #btnLogin': function (ev, template) {
        var userId = template.$('#username').val();
        //validate if userId is non-empty and valid userId before calling meteor method.
        Meteor.call('loginUser', userId, function (err, result) {
            if (err) {
                Session.set('userId', null);
                alert("There is an error while logging in.");
            } else {
                if (result === true) {
                    Session.set('userId', userId);
                    Router.go('someRouteAfterLogin'); //redirect to a different page.
                } else {
                    Session.set('userId', null);
                    alert("There is no such user.");
                }
            }
        });
    }
});

user已登录的其他模板中,获取

Template.someTemplateAfterLogin.onCreated(function () {
    //Actually, this can go inside your Router's current route's data and waitOn but for demonstration purpose
    var userId = Session.get("userId");
    if (userId) {
        this.subscribe('userInfo', userId);
    } else {
         Router.go('login'); //or whatever name you specified for login
    }
});

在服务器端,

Meteor.methods({
    'loginUser': function (userId) {
        if (typeof userId == "string") {
            var user = Users.findOne({ username: userId });
            return user ? true : false;
        }
        return false;
    }
});
Meteor.publish('userInfo', function (userId) {
    if (typeof userId == "string") {
        return Users.find({ username: userId }); //use second parameter to restrict the fields that you want to publish with something like this return Users.find({ username: userId }, { fields: { username: 1, firstName: 1 } });
    }
    return null;
});