How to protect http message from Angular 2 to Express Server

How to protect post call from angular2 application on Express server?

In my angular2 application, I have the following HTTP mail.

 const headers = new Headers();
    headers.append('Content-Type', 'application/json');

    const data = {
      email: this.form.value.email
    };

    this.http.post('http://localhost:8080/api/user/email', data, {
      headers: headers
    })

Now I want to make sure that only my angular 2 application can make a post call to the api user. I did some research on csrf in combination with Express and angular 2. In my angular 2 application, I embedded the following implementation into the app.module.ts file.

import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http';

providers: [  {
            provide: XSRFStrategy,
            useValue: new CookieXSRFStrategy('csrftoken', 'X-CSRFToken')
        } ]

I think this is the right way to implement XSRFStrategy before angular 2?

For implementation in Express, I followed several tutorials, but without any success. Most of the time I got:

ForbiddenError: invalid csrf token

How to implement part of CSRF in my Express api application. Here is my express config:

// call the packages we need
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');

app.use(bodyParser.urlencoded({
  extended: false
}));
app.use(bodyParser.json());

var port = process.env.PORT || 8080; // set our port

// ROUTES FOR OUR API
// =============================================================================
var router = express.Router();
router.use(function (req, res, next) {
  console.log('Something is happening.');
  res.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
  res.setHeader("Access-Control-Allow-Credentials", "true");
  res.setHeader("Access-Control-Allow-Methods", "POST");
  res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
  res.setHeader('Content-Type', 'application/json');
  next();
});

app.use('/api', router);

router.post('/user/email', function (req, res) {
 ..... [how to make sure that this post can only be fired from my angular 2 application ]
}

Update # 1

I did some more research and found the following in angular 2 docs:

//By default, Angular will look for a cookie called `'XSRF-TOKEN'`, and set
//* an HTTP request header called `'X-XSRF-TOKEN'` with the value of the cookie on each request,

, Express :

const cookieOptions = {
  key: 'XSRF-TOKEN',
  secure: false,
  httpOnly: false,
  maxAge: 3600000
}

var csrfProtection = csrf({
  cookie: cookieOptions
})

:

    router.post('/user/email', csrfProtection, function (req, res) {
      console.log('post incomming');
}):

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:4200
Connection:keep-alive
Content-Length:1167
Content-Type:text/html; charset=utf-8
Date:Mon, 21 Nov 2016 20:07:12 GMT
set-cookie:XSRF-TOKEN=O4JKkjAZRik2H7ml0DoxDc8s; Max-Age=3600000; Path=/
X-Content-Type-Options:nosniff
X-Powered-By:Express

:

Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Connection:keep-alive
Content-Length:38
content-type:application/json
Host:localhost:8080
Origin:http://localhost:4200
Referer:http://localhost:4200/profile/users
+4
1

CSRF Angular2 Express

Angular cookie 'XSRF-TOKEN' HTTP- 'X-XSRF-TOKEN' cookie .

, cookie XSRF-TOKEN, api, 8080. proxy.config.json.

{ 
  "/api/*" : {
    "target": "http://localhost:8080",
    "secure": false,
    "logLevel": "debug" 
  }
}

package.json scripts/start proxy.config.json:

"scripts": {
    "start": "ng serve --proxy-config proxy.config.json",
}

, npm, /api localhost: 8080. api.

http, /json.

ourfunction() {
  const headers = new Headers();
  headers.append('Content-Type', 'application/json');
  data = { key:value }

  this.http.post('/api/user/email', data, {
      headers: headers
  }).subscribe( (resp: any) => console.log('resp', resp));

}

, Angular2. Express.

var express = require('express'); 
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
var cors = require('cors')

.

const cookieOptions = {
  key: 'XSRF-TOKEN',
  secure: false,
  httpOnly: false,
  maxAge: 3600
}

const corsOptions = {
  origin: 'http://localhost:4200',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 
};

, csrf cors.

const port = process.env.PORT || 8080; // set our port
const csrfProtection = csrf({ cookie: cookieOptions })
const router = express.Router();

. .

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/api', router);
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(csrfProtection);

router.use(function (req, res, next) {
  res.setHeader('Content-Type', 'application/json');
  next();
});

, Express. CSRF.

-

var express = require('express'); 
var app = express();
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var csrf = require('csurf');
var cors = require('cors')

const cookieOptions = {
  key: 'XSRF-TOKEN',
  secure: false,
  httpOnly: false,
  maxAge: 3600
}

const corsOptions = {
  origin: 'http://localhost:4200',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 
};

const port = process.env.PORT || 8080; // set our port
const csrfProtection = csrf({ cookie: cookieOptions })
const router = express.Router();


app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use('/api', router);
app.use(cors(corsOptions));
app.use(cookieParser());
app.use(csrfProtection);

router.use(function (req, res, next) {
  res.setHeader('Content-Type', 'application/json');
  next();
});

router.post('/user/email', function (req, res) {
  console.log('post incomming');
  console.log('req', req.body);
  res.send('testing..');
});

app.listen(port);
console.log('Magic happens on port ' + port);
+1

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


All Articles