csrf-login

1.17.2 • Public • Published

csrf-login

Login from command line to the websites that use CSRF protection

NPM

Build status dependencies devdependencies semantic-release manpm

Why

CSRF tokens are a good security practice. A login form page contains a hidden input field that is sent together with the username / password pair. The server checks if the sent data contains the valid CSRF field before trying to authenticate the user.

<form method="POST" action="/login/" id="loginform">
    <input type="hidden" name="csrfmiddlewaretoken" value="<long random hash>"" />
    <input type="email" name="email" />
    <input type="password" name="password" />
</form>

There are two components to the protection: the hidden input value and a cookie. In order to successfully execute requests, for example the login POST, one needs to fetch the login page, grab the middleware token and use it to form the valid POST request, plus use the same value as a cookie when making the POST request!

csrf-login allows you to login from command line to websites that use CSRF token protection.

Install and use

Install and use under Node

npm install csrf-login --save

Create a new file csrf.json in the current working folder, place the following custom parameters into this configuration file. For example,

{
  "host": "http://my-dev-server:3000",
  "loginFormId": "loginform",
  "tokenFieldName": "csrfmiddlewaretoken",
  "loginPath": "/accounts/login/"
}

You can take a look at the defaults in src/defaults.json

From your code use the function

var csrfLogin = require('csrf-login');
csrfLogin({
    username: username,
    password: password
}).then(function (info) {
  // info = { request, requestAsync, response, conf };
  return info.requestAsync('/api/foo', { some: params });
}).then(function (data) { });

To get username and password from the user, you can use get-username-and-password.

Passing options

Instead of a JSON file, you can pass options as an object

var csrfLogin = require('csrf-login');
csrfLogin({
  host: 'https://server.com',
  username: username,
  password: password
})

You can also pass folder with the config file, for example if the csrf.json file is in the same as the caller source file. The options from the loaded file will combined with additional options.

var csrfLogin = require('csrf-login');
csrfLogin({
  folder: __dirname,
  password: password
})

You can also pass options via environment variables

USERNAME=me PASSWORD=test123 npm test

Returned object

The returned object info has several properties

csrfLogin(user)
  .then(function (info) {
    console.log(Object.keys(info))
    // [ 'request', 'requestAsync', 'response', 'config', 'jar' ]
  })

info.response

This is the response object from the login call

info.request

The request function you can use to execute other API calls (the session cookie is set for example)

csrfLogin()
  .then(function (info) {
    info.request('/some/other/end/point', function (error, response, body) {
      //Act on the response...
    });
  });

If you want to use promises instead of callbacks, use the requestAsync property

info.requestAsync

The same request object, but wrapped in a promise-returning function. For example to make another API JSON request

csrfLogin()
  .then(function (info) {
    return info.requestAsync({
      url: '/some/data/api',
      json: true
    });
  })
  .then(function (data) {
    console.log('got data from /some/data/api');
    console.log(data);
  })
  .catch(onError)
  .done();

info.config

The full configuration object, created from csrf.json, environment and command line arguments. Uses nconf. One can get the host for example

csrfLogin()
  .then(function (info) {
    console.log('logged into', info.get('host'));
  });

info.jar

The cookie jar after the login. Will contain session / auth cookies for requests.

Debugging

If you need to debug the login process, run the module with debug logging option

DEBUG=csrf node client.js

Under the hood, csrf-login is using request module, and you can enable the request debug logging

DEBUG=csrf NODE_DEBUG=request node client.js

There is a scrip demo/demo.js you can use to quickly test the login feature.

Optional Configuration

By default, a form is looked up by Id and the submitted login form fields are expected to be named email and password. You can override these defaults in the config using the loginFormSelector, loginUsernameField, and loginPasswordField.

{
  "host": "http://my-dev-server:3000",
  "loginFormSelector": "class='myForm'",
  "loginUsernameField": "username",
  "loginPasswordField": "userPassword",
  "tokenFieldName": "csrfmiddlewaretoken",
  "loginPath": "/accounts/login/"
}

Demo

I have coded a small demo server, you can start it manually using npm run demo-server then open localhost:3000, localhost:3000/login pages. You can also run unit tests against the demo server and see how the token is captured and used in the unit tests using npm run demo-test command.

Small print

Author: Gleb Bahmutov © 2015

License: MIT - do anything with the code, but don't blame me if it does not work.

Spread the word: tweet, star on github, etc.

Support: if you find any problems with this module, email / tweet / open issue on Github

MIT License

Copyright (c) 2015 Gleb Bahmutov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Package Sidebar

Install

npm i csrf-login

Weekly Downloads

26

Version

1.17.2

License

MIT

Last publish

Collaborators

  • bahmutov