Exception when using server route and onBeforeAction

I see strange behavior when trying to add a PDF file.

The following code in the if statement throws: like \ routes.js

Router.onBeforeAction(function () { if (!Meteor.user() || Meteor.loggingIn()) { this.redirect('welcome.view'); } else { Meteor.call("userFileDirectory", function (error, result) { if (error) throw error; else console.log(result); }); this.next(); } }, { except: ['welcome.view'] }); 

Error: Meteor.userId can only be called by calling a method. using this.userId in the publish function. in Object.Meteor.userId (packages / accounts-base / accounts_server.js: 19: 1) in Object.Meteor.user (packages / accounts-base / accounts_server.js: 24: 1) in [object Object] .Router. onBeforeAction.except (application / both / 3-router / routes.js: 10: 15) into packages / hardware: router / lib / router.js: 277: 1 at [object Object] ._. Extend.withValue (packages / meteor / dynamic_nodejs.js: 56: 1) in the Object.hookWithOptions object (packages / hardware: router / lib / router.js: 276: 1) in boundNext (packages / hardware: middleware-stack / lib /middleware_stack.js: 251: 1) on runWithEnvironment (packages / meteor / dynamic_nodejs.js: 108: 1) with packages / meteor / dynamic _nodejs.js: 121: 1 in [object Object] .dispatch (Packages / iron: intermediate stack / Library / middleware _stack.js: 275: 1)

Only when I add this code to the file and the / pdf route is taken:

 Router.route('/pdf', function() { var filePath = process.env.PWD + "/server/.files/users/test.pdf"; console.log(filePath); var fs = Npm.require('fs'); var data = fs.readFileSync(filePath); this.response.write(data); this.response.end(); }, { where: 'server' }); 

The above code is working fine; pdf is displayed on the screen and no exception occurs when I take out the code onBeforeAction.

The opposite is also true, if I choose the server route, there is no path that throws an exception.

0
source share
2 answers

This is because the route you are using is a server-side route. The method used by Meteor to authenticate the user is performed through the DDP protocol through websites.

When your browser makes a GET / POST to the server, it does not have any information about the authentication status of the user.

You use Meteor.user() in your Route.onBeforeAction , but it does not have access to this information.

The solution to this is to find an alternative way to authenticate the user. One of these methods is the use of cookies.

This is a known issue with the Meteor authentication system, see https://github.com/EventedMind/iron-router/issues/649

+1
source

A better way than cookies can be a named Meteor collection that stores userId and some sessionId:

You can save the current userId on the client side before calling the server:

 var sessionId = Random.id(); col = new Mongo.Collection('session'); col.insert({ sessionId: sid, userId: Meteor.userId(), issued: new Date() }); 

And then pass sessionId to the server through a GET/POST and read it on the server:

 var sid = this.request.query.sid; var user = col.findOne({sessionId: sid}); // returns an object 

Using a separate parameter is better than using userId because you can revoke this sessionId some time later or immediately after the server is called.

Proper allow/deny permissions are required so that someone does not update the collection. Also note that you cannot trust new Date() on the client side.

+1
source

Source: https://habr.com/ru/post/980337/


All Articles