Skip to content
This repository was archived by the owner on Sep 14, 2022. It is now read-only.

Exposed verify token. Fixes #43. #82

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ var csurf = require('csurf')
Create a middleware for CSRF token creation and validation. 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.
This token is validated against the visitor's session or csrf cookie. It
also adds a `req.isTokenValid(token)` function used to verify a token
(for example, when retrieving state from an oauth callback).

#### Options

Expand Down Expand Up @@ -223,6 +225,33 @@ app.use(function (err, req, res, next) {
})
```

### Verifying a token

If you need to pass the token in a query string rather than an
HTTP header, you can use the `req.isTokenValid(token)` function
provided by this middleware. This is useful when you want to
use this library with an oauth callback.

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

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

app.get('/oauth_callback', function(req, res) {
if(req.isTokenValid(req.query.state)) {
res.status(200);
res.send('Token Passed');
} else {
// handle CSRF token errors here
res.status(403)
res.send('form tampered with')
}
});

```

## License

[MIT](LICENSE)
Expand Down
10 changes: 9 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ module.exports = function csurf(options) {
return token
}

req.isTokenValid = function isTokenValid(token) {
return isvalid(tokens, secret, token);
};

// generate & set secret
if (!secret) {
secret = tokens.secretSync()
Expand Down Expand Up @@ -265,9 +269,13 @@ function setsecret(req, res, sessionKey, val, cookie) {

function verifytoken(req, tokens, secret, val) {
// valid token
if (!tokens.verify(secret, val)) {
if (!isvalid(tokens, secret, val)) {
throw createError(403, 'invalid csrf token', {
code: 'EBADCSRFTOKEN'
});
}
}

function isvalid(tokens, secret, val) {
return tokens.verify(secret, val);
}
53 changes: 53 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,59 @@ describe('csurf', function () {
})
})

describe('req.isTokenValid()', function () {
before(function(done) {
var _this = this
var app = connect()
this.app = app
app.use(session({ keys: ['a', 'b'] }))
app.use(csurf())
app.use('/token', function(req, res) {
res.end(req.csrfToken())
})
app.use('/check-token', function(req, res) {
var isValid = req.isTokenValid(req.headers['oauth-state'])
res.end(isValid ? 'PASS' : 'FAIL')
});
request(app)
.get('/token')
.expect(200, function (err, res) {
if (err) return done(err)
_this.token = res.text
_this.cookie = cookies(res)
done()
})

})
it('should pass on valid tokens', function (done) {
request(this.app)
.get('/check-token')
.set('OAUTH-STATE', String(this.token))
.set('Cookie', this.cookie)
.expect(200, 'PASS', done)
})
it('should throw on invalid tokens', function (done) {
request(this.app)
.get('/check-token')
.set('Cookie', this.cookie)
.set('OAUTH-STATE', String(this.token + 'p'))
.expect(200, 'FAIL', done)
})
it('should throw on attempting someone else\'s token', function(done) {
var _this = this;
request(this.app)
.get('/token')
.expect(200, function (err, res) {
if (err) return done(err)
request(_this.app)
.get('/check-token')
.set('Cookie', _this.cookie)
.set('OAUTH-STATE', String(res.text))
.expect(200, 'FAIL', done)
})
});
})

describe('when using session storage', function () {
var app
before(function () {
Expand Down