title: getting csrf working expressjs angularjs nginx
body: <p>I'm having trouble setting up (understanding?) csrf protection. My setup is nginx serving static files with expressjs for api calls and angularjs front end. All calls to /api/* are sent to express, anything else is handled by nginx. </p>
  
  <p>I have my login system setup and working fine (without csrf protection). I used the example here ( <a href="http://mircozeiss.com/using-csrf-with-express-and-angular/" rel="nofollow">http://mircozeiss.com/using-csrf-with-express-and-angular/</a> ) but I keep getting 403 forbidden. (once in a while the login works, till i logout and re-login).</p>
  
  <p>Here's my relevant code:</p>
  
  <p>//nginx</p>
  
  <pre><code>server {
  listen 80;
  server_name login.example.dev;
  root /home/example/www/login/pub;
  index index.html;
  
  location /api {
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header Host $proxy_host;
      proxy_pass_header X-XSRF-TOKEN;
      proxy_pass http://127.0.0.1:8000;
  }
  
  location / {
      if ($args ~ "_escaped_fragment_=(.*)") {
              rewrite ^ /snapshots/$1;
      }
      try_files snapshots$request_uri.html $uri /index.html;
  }
  }
  </code></pre>
  
  <p>//server.js</p>
  
  <pre><code>var config=require('./config.js');
  var express = require('express');
  var http = require('http');
  var RedisStore=require('connect-redis')(express);
  var member=require('./routes/member.js');
  var auth=require('./routes/auth.js');
  var app = express();
  
  app.configure(function(){
  
      app.enable('trust proxy');
      app.set('port', process.env.PORT || config.app.port);
      app.use(express.bodyParser());
      app.use(express.methodOverride());
      app.use(express.cookieParser());
      app.use(express.session({
      proxy:true,
        secret: config.session.secret,
        store: new RedisStore({db:config.session.redis.db,prefix:config.session.redis.prefix}),
        key: config.session.key,
        cookie:{
          domain:config.session.domain,
          maxAge:config.session.maxAge
        }
      }));
  
      app.use(express.csrf());
      app.use(function(req, res, next) {
            res.cookie('XSRF-TOKEN', req.csrfToken(),{httpOnly:true,domain:'.example.dev'});
            next();
      });
      app.use(app.router);
  });
  
  app.get(config.app.prefix+'/member/get-data.json',restrict,member.getData);
  app.post(config.app.prefix+'/auth/login',auth.login);
  app.get(config.app.prefix+'/auth/logout', auth.logout);
  
  http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
  });
  
  function restrict(req,res,next){
          if(config.session.dataKey in req.session){
              var d=req.session[config.session.dataKey];
              req.session.regenerate(function(err){
                  if(err){
                      console.log('Err regen session');
                  }else{
                      req.session[config.session.dataKey]=d;
                      next();
                  }
              });
          }else{
              req.session.destroy();
              res.json(401,{"msg":"not logged in."});
          }
  
  }
  </code></pre>
  
  <p>//angularjs</p>
  
  <pre><code>var loginCtrl = lmu.controller('LoginCtrl',['$scope','$http','User','$location',
  function($scope,$http,User,$l){
  
      $scope.cred={};
  
  
      $scope.login=function(){
          $http.post('/api/auth/login',$scope.cred).then(function(res){
                  User.data=res.data;
                  $l.path('/account');
          },function(e){
                  User.data=e.data;
          });
      };
  </code></pre>
  
  <p>}]);</p>