Skip to content

Commit

Permalink
Merge pull request #3 from melophonic/master
Browse files Browse the repository at this point in the history
electrode-csrf-jwt demo
  • Loading branch information
ananavati authored Sep 10, 2016
2 parents b89b401 + 55d0b2b commit 75f70df
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 2 deletions.
84 changes: 84 additions & 0 deletions client/components/csrf.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from "react";

export class CSRF extends React.Component {

constructor() {
super();
this.state = {
testResult: ""
};
this.testValid = this.testValid.bind(this);
this.testInvalid = this.testInvalid.bind(this);
}

doPost(csrfToken, shouldFail) {
fetch('/2', {
credentials: 'same-origin',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'x-csrf-jwt': csrfToken
},
body: JSON.stringify({message: "hello"})
})
.then((resp) => {
if (resp.status == "200") {
this.setState({testResult: "POST SUCCEEDED with status " + resp.status});
} else {
this.setState({testResult: "POST FAILED with status " + resp.status});
}

})
.catch((e) => {
this.setState({testResult: "POST FAILED:" + e.toString()});
});
}

testValid() {
this.setState({testResult: "valid"});
fetch("/1", {credentials: 'same-origin'}) // eslint-disable-line
.then((resp) => {
if (resp.status == "200") {
const token = resp.headers.get('x-csrf-jwt');
if (token != '') {
console.log("Got CSRF token OK");
this.doPost(token, false);
} else {
this.setState({testResult: "Unable to get token from GET request"});
}
} else {
this.setState({testResult: "GET request returned " + resp.status});
}
})
.catch((e) => {
this.setState({testResult: e.toString()});
});
}

testInvalid() {
this.doPost("fake", true);
}

render() {
const text = this.state.testResult;
return (
<div>
<h1>Electrode CSRF-JWT Demo</h1>
<p>This component demonstrates usage of the <a href="https://github.com/electrode-io/electrode-csrf-jwt">electrode-csrf-jwt</a> module. Two endpoints are declared in <code>server/plugins/demo.js</code>:</p>
<ul>
<li>a GET endpoint, <code>/1</code>, to which the module automatically adds a csrf token header</li>
<li>a POST endpoint, <code>/2</code>, to which the module automatically ensures the presence of a valid token in the request headers</li>
</ul>
<p>Two simple tests via AJAX (JavaScript must be enabled) are demonstrated below:</p>
<ul>
<li><a href="#" onClick={this.testValid}>Test Valid POST</a> using a token retrieved from <code>/1</code> first (should succeed with a 200 status)</li>
<li><a href="#" onClick={this.testInvalid}>Test Invalid POST</a> using a forged token (should fail with a 400 status)</li>
</ul>
<div>
{text}
</div>
</div>
);
}
}
8 changes: 7 additions & 1 deletion client/components/home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import React from "react";
export class Home extends React.Component {
render() {
return (
<div><h1>Hello <a href="https://github.com/electrode-io">Electrode</a></h1></div>
<div>
<h1>Hello <a href="https://github.com/electrode-io">Electrode</a></h1>
<h2>Demonstration Components</h2>
<ul>
<li><a href="/csrf">CSRF protection using electrode-csrf-jwt</a></li>
</ul>
</div>
);
}
}
6 changes: 5 additions & 1 deletion client/routes.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react";
import { Route, IndexRoute} from "react-router";
import { Home } from "./components/home";
import { CSRF } from "./components/csrf";

export const routes = (
<Route path="/" component={Home} />
<Route path="/">
<IndexRoute component={Home} />
<Route path="csrf" component={CSRF} />
</Route>
);
7 changes: 7 additions & 0 deletions config/default.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"plugins": {
"electrode-csrf-jwt": {
"options": {
"secret": "shhhhhh",
"expiresIn": 60
}
},
"./server/plugins/csrf": {},
"webapp": {
"module": "./server/plugins/webapp",
"options": {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"bluebird": "^2.10.2",
"electrode-csrf-jwt": "^3.0.1",
"electrode-router-resolver-engine": "^1.0.0",
"electrode-server": "^1.0.0",
"electrode-static-paths": "^1.0.0",
Expand Down
34 changes: 34 additions & 0 deletions server/plugins/csrf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use strict";
/*eslint-env es6*/
var plugin = {};

/*
Sample endpoints to demonstrate CSRF protection via the electrode-csrf-jwt module.
Note the endpoints require no special configuration for protection to be enabled.
*/
plugin.register = function (server, options, next) {
/* a demo GET endpoint which will return a CSRF cookie + header */
server.route({
method: "GET",
path: "/1",
handler: function (req, reply) {
reply("valid");
}
});
/* a demo POST endpoint which will require a CSRF cookie + header */
server.route({
method: "POST",
path: "/2",
handler: function (req, reply) {
reply("valid");
}
});
next();
};

plugin.register.attributes = {
name: "CSRFPlugin",
version: "0.0.1"
};

module.exports = plugin;

0 comments on commit 75f70df

Please sign in to comment.