Logging in from Command Line
heyjordn opened this issue ยท 11 comments
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.
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
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
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.
Agreed, prefer using JSON, I'll do some more testing and let you know if anything changes. Thanks for the help ๐
@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.
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)
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.
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..
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
Ok, going to deploy the update on the live service. LMK if everything is ๐