New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging in from Command Line #55

Open
Pr0x1m4 opened this Issue Nov 23, 2017 · 11 comments

Comments

Projects
None yet
2 participants
@Pr0x1m4
Contributor

Pr0x1m4 commented Nov 23, 2017

Hi, Im trying to build a hashbase-cli around the api routes found here, however when attempting to do a POST to route /v1/login, I always seem to get a 403 forbidden response. Here's my code

const config = require("../../config/index");
const prompt = require("prompt");
const got = require("got");

  let username;
  let password;
  try {
    let result = await prompUser();
    //https://hashbase.io/v1/login
    response = await got.post(config.loginUser, {
      body: {
        username: result.username,
        password: result.password
      },
      json: true
    });
  } catch (error) {
    console.log("Error!");
    console.log(error);
  }

My JSON payload contains username and password but looking at the docs it expects email and password. As opposed to the source that expects username.

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

Whoops yeah, looks like the docs are wrong on that. I'll correct it in a moment.

Your usage looks correct to me. Here's the relevant test: https://github.com/beakerbrowser/hashbase/blob/master/test/users.js#L264

Member

pfrazee commented Nov 24, 2017

Whoops yeah, looks like the docs are wrong on that. I'll correct it in a moment.

Your usage looks correct to me. Here's the relevant test: https://github.com/beakerbrowser/hashbase/blob/master/test/users.js#L264

@Pr0x1m4

This comment has been minimized.

Show comment
Hide comment
@Pr0x1m4

Pr0x1m4 Nov 24, 2017

Contributor

Thanks, that test was the next thing I viewed 😄 but, looking closer at the source you have csrf middleware enabled. From what I gathered, through testing, I'd need to pass csrf token in the x-csrf-token as well as in the body of POST request.
Here's what I've been using to try and get the csrf token.

"use strict";
var request = require("request");
var cookieJar = request.jar();
request = request.defaults({ jar: cookieJar });
var baseURL = "https://hashbase.io/v1";
const getCsrfFromCookie = cookie => {
  // Extracts csrf value from the following eg.
  //_csrf=KRw608J6zHkefwUvrRq-wRMx; Path=/;
  return cookie.substring(6, cookie.length - 8);
};
request(
  {
    url: baseURL + "/login",
    method: "GET",
    jar: cookieJar,
    followAllRedirects: true
  },
  function(error, httpResponse, body) {
    if (error) {
      console.error(error);
      return;
    }

    let cookies = cookieJar.getCookies(baseURL + "/login");
    let csrfToken = getCsrfFromCookie(String(cookies[0]));

    request(
      {
        method: "POST",
        url: baseURL + "/login",
        contentType: "application/json",
        headers: {
          "x-csrf-token": csrfToken
        },
        json: true,
        body: {
          username: "prx01m4",
          password: "*********",
          _csrf: csrfToken
        },
        followAllRedirects: true
      },
      function(error, httpResponse, body) {
        console.log(body);
        if (error) {
          console.error(error);
          return;
        }
      }
    );
  }
);

I'm wondering if I should just sent data as application/x-www-form-urlencoded instead of json

Contributor

Pr0x1m4 commented Nov 24, 2017

Thanks, that test was the next thing I viewed 😄 but, looking closer at the source you have csrf middleware enabled. From what I gathered, through testing, I'd need to pass csrf token in the x-csrf-token as well as in the body of POST request.
Here's what I've been using to try and get the csrf token.

"use strict";
var request = require("request");
var cookieJar = request.jar();
request = request.defaults({ jar: cookieJar });
var baseURL = "https://hashbase.io/v1";
const getCsrfFromCookie = cookie => {
  // Extracts csrf value from the following eg.
  //_csrf=KRw608J6zHkefwUvrRq-wRMx; Path=/;
  return cookie.substring(6, cookie.length - 8);
};
request(
  {
    url: baseURL + "/login",
    method: "GET",
    jar: cookieJar,
    followAllRedirects: true
  },
  function(error, httpResponse, body) {
    if (error) {
      console.error(error);
      return;
    }

    let cookies = cookieJar.getCookies(baseURL + "/login");
    let csrfToken = getCsrfFromCookie(String(cookies[0]));

    request(
      {
        method: "POST",
        url: baseURL + "/login",
        contentType: "application/json",
        headers: {
          "x-csrf-token": csrfToken
        },
        json: true,
        body: {
          username: "prx01m4",
          password: "*********",
          _csrf: csrfToken
        },
        followAllRedirects: true
      },
      function(error, httpResponse, body) {
        console.log(body);
        if (error) {
          console.error(error);
          return;
        }
      }
    );
  }
);

I'm wondering if I should just sent data as application/x-www-form-urlencoded instead of json

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

Oh brother- right, I forgot about that. That's a pain for you! You may have the right solution but I'll see if there's something cleaner that we can do.

I'd suggest you stay with JSON. I prefer that as an exchange format. If there's some feature that works differently by the encoding, we should change it.

Member

pfrazee commented Nov 24, 2017

Oh brother- right, I forgot about that. That's a pain for you! You may have the right solution but I'll see if there's something cleaner that we can do.

I'd suggest you stay with JSON. I prefer that as an exchange format. If there's some feature that works differently by the encoding, we should change it.

@Pr0x1m4

This comment has been minimized.

Show comment
Hide comment
@Pr0x1m4

Pr0x1m4 Nov 24, 2017

Contributor

Agreed, prefer using JSON, I'll do some more testing and let you know if anything changes. Thanks for the help 😄

Contributor

Pr0x1m4 commented Nov 24, 2017

Agreed, prefer using JSON, I'll do some more testing and let you know if anything changes. Thanks for the help 😄

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

@Pr0x1m4 Based on the csurf's readme, it looks like you can pass the token as {_csrf:} in the body. See https://github.com/expressjs/csurf#value. That might be easier.

Extracting the token from the cookies is a pain. Maybe we should add a route like /v1/csrf which would fetch a token for API calls.

Member

pfrazee commented Nov 24, 2017

@Pr0x1m4 Based on the csurf's readme, it looks like you can pass the token as {_csrf:} in the body. See https://github.com/expressjs/csurf#value. That might be easier.

Extracting the token from the cookies is a pain. Maybe we should add a route like /v1/csrf which would fetch a token for API calls.

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

screen shot 2017-11-24 at 11 13 35 am

Whoops JK. Will look around for better options.

Member

pfrazee commented Nov 24, 2017

screen shot 2017-11-24 at 11 13 35 am

Whoops JK. Will look around for better options.

@Pr0x1m4

This comment has been minimized.

Show comment
Hide comment
@Pr0x1m4

Pr0x1m4 Nov 24, 2017

Contributor

Thought that would've been a security issue too.
One thought might be to include an API key for each user account (or have them generate it) and send that in JSON body when logging in.

So a registered user might want to use cli to push archives instead of Web UI, he/she would first have to go to hashbase.io generate an unique API key, then configure hashbase-cli to use that to authenticate (along with username and password)

Contributor

Pr0x1m4 commented Nov 24, 2017

Thought that would've been a security issue too.
One thought might be to include an API key for each user account (or have them generate it) and send that in JSON body when logging in.

So a registered user might want to use cli to push archives instead of Web UI, he/she would first have to go to hashbase.io generate an unique API key, then configure hashbase-cli to use that to authenticate (along with username and password)

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

According to https://github.com/pillarjs/understanding-csrf, if we disable CORS on effectful methods and and only accept JSON on those same methods, then we don't need CRSF.

So, one option would be to disable CORS and then either stop using urlencoded, or just require CSRF on urlencoded.

Member

pfrazee commented Nov 24, 2017

According to https://github.com/pillarjs/understanding-csrf, if we disable CORS on effectful methods and and only accept JSON on those same methods, then we don't need CRSF.

So, one option would be to disable CORS and then either stop using urlencoded, or just require CSRF on urlencoded.

@Pr0x1m4

This comment has been minimized.

Show comment
Hide comment
@Pr0x1m4

Pr0x1m4 Nov 24, 2017

Contributor

Ok great, so what would be the next steps? I could would more than willing to work getting that feature done in order to facilitate the cli. Would we just disable CORS on just api routes like /v1/login etc..

Contributor

Pr0x1m4 commented Nov 24, 2017

Ok great, so what would be the next steps? I could would more than willing to work getting that feature done in order to facilitate the cli. Would we just disable CORS on just api routes like /v1/login etc..

@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 24, 2017

Member

That would make sense. We need to double check that the hashbase frontend would still work.

Action items:

  • Disable CORS and disable urlencoded submissions to the API routes
  • Disable CSRF on the API routes
  • Make sure the frontend still works
Member

pfrazee commented Nov 24, 2017

That would make sense. We need to double check that the hashbase frontend would still work.

Action items:

  • Disable CORS and disable urlencoded submissions to the API routes
  • Disable CSRF on the API routes
  • Make sure the frontend still works
@pfrazee

This comment has been minimized.

Show comment
Hide comment
@pfrazee

pfrazee Nov 29, 2017

Member

Ok, going to deploy the update on the live service. LMK if everything is 👍

Member

pfrazee commented Nov 29, 2017

Ok, going to deploy the update on the live service. LMK if everything is 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment