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:
var express = require('express');
var app = 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;
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