Check headers on each page request

淺唱寂寞╮ 提交于 2019-12-23 17:02:14

问题


I need to check the request headers on each page request. I thought the place to try this would be in the 'apostrophe-express' module. I've created my own module 'auth' that extends 'apostrophe-express':

module.exports = {
extend: 'apostrophe-express',
name: 'auth',
alias: 'auth',
absoluteUrl: function(req, res, next){
    console.log(req);
 }
};

But this isn't working. I'm getting an error 'apostrophe-templates\index.js" 597 req.browserCall('apos.pageReadywhenCalm($("body"));')'

Can you tell me where I should hook into each page request to run some custom checking/rule (e.g. if a certain cookie isnt present, then redirect the user to a different site)?

Thanks!


回答1:


I'm the principal architect of Apostrophe at P'unk Avenue.

You don't want to extend the apostrophe-express module under a new name. That module provides the apos.app singleton, so extending it under a new name just sets up apos.app twice, leading to confusion and potential problems.

Intercepting every Express request

Instead, just leverage the middleware option of the apostrophe-express module. You can do that in app.js:

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
    'apostrophe-express': {
      middleware: [
        function(req, res, next) {
          // Do whatever you like here
          console.log(req.url);
          // Let the request continue. You could also
          // use res.redirect, res.send, etc. and
          // bypass Apostrophe, in which case you
          // should NOT call next
          return next();
        }
      ]
    }
  }
});

This is all you need, and you could use require to pull the middleware function in from another file, reducing clutter in app.js. However it's worth pointing out that you can move this code to a lib/modules/apostrophe-express/index.js file in your project, to "implicitly subclass" that module. That opens the door to providing your own construct property as well, which would permit you to override any of the methods of the module if you wanted to.

If you approach it this way, you don't need to touch app.js at all:

// in lib/modules/apostrophe-express/index.js at project level
module.exports = {
  middleware: [
    function(req, res, next) {
      console.log(req.url);
      return next();
    }
  ],
  construct: function(self, options) {
    // If you want, override methods of the module here   
  };
};

Intercepting the request just before page rendering

You specified "each page request," which I've interpreted to mean "each web request." But it's possible you specifically only want requests where Apostrophe is about to build and send a proper webpage.

For that, just add a pageBeforeSend method to any of your own modules. Let's say our module is called cool-stuff:

// in app.js

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
   'cool-stuff': {}
  }
});


// In lib/modules/cool-stuff/index.js

module.exports = {
  construct: function(self, options) {
    self.pageBeforeSend = function(req, callback) {
      // Careful, there isn't always a page object; we could be
      // rendering /login for instance
      console.log(req.data.page && req.data.page._url);
      return callback(null);
    };
  }
};

Apostrophe always calls pageBeforeSend for every module that has such a method.

As seen above, take care not to assume req.data.page is set, since there are a few cases where Apostrophe renders a full webpage as a response but there is no corresponding page object in Apostrophe's page tree.

Intercepting right after the page object is loaded

One more option: if pageBeforeSend is too late in the process for you, for instance because you want widget loaders to see changes you've made to req, use pageServe instead...

// in app.js

var apos = require('apostrophe')({
  modules: {
    // Other module configuration here, then ...
   'cool-stuff': {}
  }
});

// lib/modules/cool-stuff/index.js

module.exports = {
  construct: function(self, options) {
    self.pageServe = function(req, callback) {
      // Express request URL
      console.log(req.url);
      // URL of the best matching page available
      console.log((req.data.page || req.data.bestPage)._url);
      return callback(null);
    };
  }
};

Notice that I'm allowing for either req.data.page or req.data.bestPage to exist. If the URL doesn't exactly match a page, Apostrophe will set req.data.bestPage to the page with the longest "path prefix" matching the URL. For instance, if the URL is /foo/bar and /foo exists but /foo/bar doesn't, req.data.bestPage will be /foo. Note that this means req.data.bestPage will be the homepage in the worst case.

See the apostrophe-custom-pages module for neat things you can do with this.

Hope this is helpful!



来源:https://stackoverflow.com/questions/39785274/check-headers-on-each-page-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!