# csurf

[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build status][travis-image]][travis-url]
[![Test coverage][coveralls-image]][coveralls-url]

Node.js [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection middleware.

Requires either a session middleware or [cookie-parser](https://www.npmjs.com/package/cookie-parser) to be initialized first.
- [express-session](https://www.npmjs.com/package/express-session)
- [cookie-session](https://www.npmjs.com/package/cookie-session)

If you have questions on how this module is implemented, please read
[Understanding CSRF](https://github.com/pillarjs/understanding-csrf).

### Install

```sh
$ npm install csurf
```

## API

```js
var csrf = require('csurf')
```

### csrf(options)

This middleware adds a `req.csrfToken()` function to make a token which should be added to requests which mutate state, within a hidden form field, query-string etc. This token is validated against the visitor's session or csrf cookie.

#### Options

- `value` a function accepting the request, returning the token.
  - The default function checks four possible token locations:
    - `_csrf` parameter in `req.body` generated by the `body-parser` middleware.
    - `_csrf` parameter in `req.query` generated by `query()`.
    - `x-csrf-token` and `x-xsrf-token` header fields.
- `cookie` set to a truthy value to enable cookie-based instead of session-based csrf secret storage.
  - If `cookie` is an object, these options can be configured, otherwise defaults are used:
    - `key` the name of the cookie to use (defaults to `_csrf`) to store the csrf secret
    - any other [res.cookie](http://expressjs.com/4x/api.html#res.cookie) options can be set
- `ignoreMethods` An array of the methods CSRF token checking will disabled.
  (default: `['GET', 'HEAD', 'OPTIONS']`)

### req.csrfToken()

Lazy-loads the token associated with the request.

## Example

### Simple express example

The following is an example of some server-side code that protects all
non-GET/HEAD/OPTIONS routes with a CSRF token.

```js
var express = require('express')
var csrf    = require('csurf')

var app = express()
app.use(csrf())

// error handler
app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)

  // handle CSRF token errors here
  res.status(403)
  res.send('session has expired or form tampered with')
})

// pass the csrfToken to the view
app.get('/form', function(req, res) {
  res.render('send', { csrfToken: req.csrfToken() })
})
```

Inside the view (depending on your template language; handlebars-style
is demonstrated here), set the `csrfToken` value as the value of a hidden
input field named `_csrf`:

```html
<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="{{csrfToken}}">
  
  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
```

### Custom error handling

```js
var express = require('express')
var csrf    = require('csurf')

var app = express()
app.use(csrf())

// error handler
app.use(function (err, req, res, next) {
  if (err.code !== 'EBADCSRFTOKEN') return next(err)

  // handle CSRF token errors here
  res.status(403)
  res.send('session has expired or form tampered with')
})
```

## License

[MIT](LICENSE)

[npm-image]: https://img.shields.io/npm/v/csurf.svg?style=flat
[npm-url]: https://npmjs.org/package/csurf
[travis-image]: https://img.shields.io/travis/expressjs/csurf.svg?style=flat
[travis-url]: https://travis-ci.org/expressjs/csurf
[coveralls-image]: https://img.shields.io/coveralls/expressjs/csurf.svg?style=flat
[coveralls-url]: https://coveralls.io/r/expressjs/csurf?branch=master
[downloads-image]: https://img.shields.io/npm/dm/csurf.svg?style=flat
[downloads-url]: https://npmjs.org/package/csurf
