How to get current user in custom route?

2019-08-30 11:34发布

As per this answer I created my own route so that I could handle file uploads. Here's what I've got:

var router = Connect.middleware.router(function(route) {
    route.post('/upload', function(req, res) {
        var filename = req.headers['x-filename'];
        var path = Path.join('.uploads', filename);
        var writeStream = FileSystem.createWriteStream(path);
        writeStream.on('error', function(e) {
            console.error(e);
            res.writeHead(500);
            res.end();
        }).on('close', function() {
            Fiber(function() {
                console.log(Meteor.user());
            }).run();
            res.writeHead(200);
            res.end();
        });
        req.pipe(writeStream);
    });
});
app.use(router);

This works great for uploading files, but when I try to acess Meteor.user() it gives me:

app/server/main.js:24
            }).run();
               ^
Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.
    at Object.Meteor.userId (app/packages/accounts-base/accounts_server.js:95:13)
    at Object.Meteor.user (app/packages/accounts-base/accounts_server.js:100:25)
    at app/server/main.js:23:36
Exited with code: 1

I can't see anything in the req object that might help me out.

Is there any way to get access to the user object?


For the time being, I'm getting the user ID client side and passing it along through the headers which I then use to look up server side:

route.post('/upload', function(req, res) {
    Fiber(function() {
        var userId = req.headers['x-userid'];
        var user = Meteor.users.findOne({_id:userId});
        if(user) {
            ...
        } else {
            res.writeHead(403,'User not logged in');
            res.end();
        }
    }).run();
});

I don't like this because it's not at all secure. It would be easy to upload something under a different user's account.

Edit: Nevermind. The very act of calling Meteor.users.findOne({_id:userId}); somehow breaks the upload stream. Every file gets corrupt as soon as I put that in; they upload up to about 700 KB and then just stop and close the connection without error.

标签: meteor
2条回答
贪生不怕死
2楼-- · 2019-08-30 11:59

If it's still valid question.

The problem is that there is no way how to get Meteor.user() in this part of code.

But you can always reach Meteor.userId .. and it's not null if user is logged in .. so you can upload only for logged user. (if req.headers['x-userid'] == Meteor.userId)

The very act of calling Meteor.users.findOne({_id:userId}); somehow breaks the upload stream.

Because it's reactive part.. so every time if Meteor.users collection is updated this part of code is executed again.

So if you can use only Meteor.userId (which is changed only if user is logged in/out) it should work fine.

查看更多
在下西门庆
3楼-- · 2019-08-30 12:06

I've run into this quite a few times, and it's frustrating. I don't think you can make Meteor.userId() calls from inside a fiber. I usually do a var userId = Meteor.userId(); before I call the fiber, and then reference that variable instead.

查看更多
登录 后发表回答