NodeJS Request - login into website - javascript

i'm very new to Javascript and i just want to login into website from NodeJS request. This website need information from the first time visited to login.
Here is my code.
var cheerio = require('cheerio');
var loginLink = 'link';
var loginJar = request.jar();
var ltValue = '';
request.get({url: loginLink, jar: loginJar}, function(err, httpResponse, html)
{
var dat = cheerio.load(html);
var arr = dat('input[name="lt"]');
ltValue = arr.attr('value');
arr = dat('input[name="execution"]');
executionValue = arr.attr('value');
/*Post body*/
var loginBody = 'username=' + usn + '&password=' + pwd + '&lt=' + ltValue + '&execution=' + executionValue
request.post({url: loginLink, jar: loginJar, method: 'post', json: true, body: loginBody, }}, function(err, res, b)
{
if (b.indexOf('errors') != -1)
console.log("Success");
else console.log("Fail");
});
});
I have write try it in C# and it work correctly but in my NodeJs code it always return fail. I have tried everytime but i couldn't do it. Please help me with this problem.
byte[] binData = Encoding.ASCII.GetBytes(loginBody)
string loginFile = "loginInfo.txt";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("link");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = binData.Length;
request.CookieContainer = cookieContainer;
using (Stream stream = request.GetRequestStream())
{
stream.Write(binData, 0, binData.Length);
}
WebResponse response = request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
File.WriteAllText(loginFile, reader.ReadToEnd());
}
string loginData = userID + " " + password;
File.WriteAllText("login.txt", loginData);

Related

Authorization Failed while making GET Request to Azure Blob Storage [REST API][Azure Blob Storage]

I am trying to make a GET request to get Account details of my Azure Blob Storage account, but it shows Auth failed each and every time.
Can anyone tell whether the Header or Signature String formed is correct or is there any other issue?
Here's the code:
const account = process.env.ACCOUNT_NAME || "";
const key = process.env.ACCOUNT_KEY || "";
var strTime = new Date().toUTCString();
var strToSign =
"GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
strTime +
`\nx-ms-version:2018-03-28\n/${account}/\ncomp:properties\nrestype:account`;
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:${hashInBase64}`;
const options = {
url: `https://${account}.blob.core.windows.net/?comp=properties&restype=account`,
headers: {
Authorization: auth,
"x-ms-date": strTime,
"x-ms-version": "2018-03-28",
},
};
function callback(error, response, body) {
var json = parser.toJson(body);
console.log(error);
console.log(response);
if (!error && response.statusCode == 200) {
var json = parser.toJson(body);
console.log(json);
}
}
request(options, callback);
After this, the response.statusCode which I am getting is Status 403.
statusCode: 403,
statusMessage: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.',
The details about the azure-blob and headers and Auth could be found here:
https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key
https://learn.microsoft.com/en-us/rest/api/storageservices/get-account-information
EDIT:
The string param = has been corrected to :
It will be much easier using Azure Storage JS SDK to make requests to Azure Blob Storage. If you want to get your storage account information, just try code below:
const { BlobServiceClient, StorageSharedKeyCredential } = require("#azure/storage-blob");
const account = '<storage account name>'
const accountKey = '<storage account key>'
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
const blobServiceClient = new BlobServiceClient(
`https://${account}.blob.core.windows.net`,
sharedKeyCredential
);
blobServiceClient.getAccountInfo().then((result)=>{
console.log("accountKind:"+result.accountKind + " skuName:" + result.skuName + " version:" + result.version );
})
Result:
Update:
If you want to try it in a more generic fashion, try the code below:
var CryptoJS = require("crypto-js");
var request = require("request");
var parser = require('body-parser')
const account = ''
const key = ''
var strTime = new Date().toUTCString();
var strToSign =
"GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:" +
strTime +
`\nx-ms-version:2018-03-28\n/${account}/\ncomp:properties\nrestype:account`;
//console.log(strToSign);
var secret = CryptoJS.enc.Base64.parse(key);
var hash = CryptoJS.HmacSHA256(strToSign, secret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
var auth = `SharedKey ${account}:${hashInBase64}`;
const options = {
url: `https://${account}.blob.core.windows.net/?comp=properties&restype=account`,
headers: {
Authorization: auth,
"x-ms-date": strTime,
"x-ms-version": "2018-03-28",
},
};
function callback(error, response, body) {
console.log(body);
if (!error && response.statusCode == 200) {
console.log(response.headers["x-ms-sku-name"]);
}
}
request(options, callback);
Result:
Seems you should use : instead of = in last param of your strToSign .

ASP.NET REST POST - JavaScript (jQuery) Send Body in POST

I have a REST call that is working fine when I call it from a C# app, but I can't make my JavaScript page send the content in the body of the POST. This is the REST controller. Note the JavaScript below works fine if I remove the "FromBody" attribute from the call.
[Route("api/[controller]")]
public class AuthenticateController : Controller
{
[HttpPost]
public ActionResult Post([FromBody] CredentialsModel credentialsModel)
{
var authenticationModel = new AuthenticationModel { IsSuccess = false };
if (credentialsModel != null && !string.IsNullOrEmpty(credentialsModel.Username) && !string.IsNullOrEmpty(credentialsModel.Password))
{
authenticationModel = SecurityBusinessLayer.IsValidUser(credentialsModel.Username, credentialsModel.Password);
}
var json = JsonConvert.SerializeObject(authenticationModel, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Serialize });
return Content(json);
}
}
This is the JavaScript using JQuery:
function authenticate(username, password)
{
//Get the authenticate api url
var uriHref = window.location.href;
var lastIndexOfSlash = uriHref.lastIndexOf('/');
var apiPath = uriHref.substring(0, lastIndexOfSlash) + "/api";
var encodedUri = encodeURI(apiPath + "/authenticate/");
var credentials = {};
credentials["Username"] = username;
credentials["Password"] = password;
//Post the username and password to the server
$.post(encodedUri, credentials, function (data)
{
//Parse the returned data (should match Adapt.Data.Generic.AuthenticationModel)
var response = JSON.parse(data);
if (response.IsSuccess)
{
//Ensure the token will expire
var expiryDate = new Date();
expiryDate = new Date(expiryDate.setTime(expiryDate.getTime() + 86400000));
//Set the auth token cookie
var cookieString = "authToken=" + response.Authtoken + "; expires=" + expiryDate.toUTCString() + ";path=/";
document.cookie = cookieString;
//Goto the xivic app page
window.location = "Index.html";
}
else
{
//Failed to log in, show error message
$("#badLoginMessage").css("visibility", "visible");
}
});
}
When you remove [FromBody, you have to post Json object instead of array]
$.ajax({
url: encodedUri,
type: 'POST',
data: {
Username: jsonString,Password:password
},
success: function (data) {
if (data.Success == true) {
}
else
{
}
},
error: function () {
},
complete: function () {
}
});
This is the working code based on #LeTungAnh, and #ibubi's code. I can't help but think that $post would still be a better method though. The reason $post was not working was that it was not sending a content type of application/json which is what ASP.NET Core requires.
function authenticate(username, password) {
//Get the authenticate api url
var uriHref = window.location.href;
var lastIndexOfSlash = uriHref.lastIndexOf('/');
var apiPath = uriHref.substring(0, lastIndexOfSlash) + "/api";
var encodedUri = encodeURI(apiPath + "/authenticate/");
var credentials = {};
credentials["Username"] = username;
credentials["Password"] = password;
var credentialsJson = JSON.stringify(credentials);
$.ajax({
url: encodedUri,
type: 'POST',
data: credentialsJson,
contentType: 'application/json',
success: function (responseJson) {
var authenticationObject = JSON.parse(responseJson)
if (authenticationObject.IsSuccess == true) {
//Ensure the token will expire
var expiryDate = new Date();
expiryDate = new Date(expiryDate.setTime(expiryDate.getTime() + 86400000));
//Set the auth token cookie
var cookieString = "authToken=" + authenticationObject.Authtoken + "; expires=" + expiryDate.toUTCString() + ";path=/";
document.cookie = cookieString;
//Goto the xivic app page
window.location = "Index.html";
}
else {
//Failed to log in, show error message
$("#badLoginMessage").css("visibility", "visible");
}
},
error: function () {
//Failed to log in, show error message
$("#badLoginMessage").css("visibility", "visible");
},
complete: function () {
}
});
}

Node JS Http.get file from aspx

I'm attempting to download a PDF document from any of the 'download' buttons on this website using Node's Http module. How can I download the PDF document without downloading the aspx file instead, which is what is happening with my code? For some reason, my code downloads an aspx file that says 'Error Message - File does not exist or you do not have permission to view this file', even though I can easily download the file from my web browser. Here is my code:
var pdf_text = require("pdf-text");
var request = require("request");
var http = require("http");
var fs = require("fs");
var cheerio = require("cheerio");
var urllib = require("url");
var path = "final.pdf";
var url = "http://www2.nationalgrid.com/UK/Industry-information/System-charges/Electricity-transmission/Assistance-for-areas-with-high-distribution-costs/";
var links = [];
request(url, function(error, response, html) {
if(!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$(".txtLnk").each(function() {
links.push("http://www2.nationalgrid.com" + $(this).attr("href"));
});
var file = fs.createWriteStream(urllib.parse(links[1]).pathname.split('/').pop());
var options = {
host: urllib.parse(links[1]).host,
port: 80,
path: urllib.parse(links[1]).pathname,
headers: {
"User-Agent": "Mozilla/5.0 (X11; Linux i686; rv:43.0) Gecko/201001101 Firefox/43.0"
}
};
http.get(options, function(res) {
res.on('data', function(data) {
file.write(data);
}).on('end', function() {
file.end();
});
});
console.log(links);
}
});
function data_from_pdf(pdf) {
pdf_text("pdf/" + pdf, function(err, chunks) {
var data = chunks.join("").substring(chunks.join("").search("(p/kWh)") + 6, chunks.join("").search("(p/kWh)") + 21);
var date = data.substring(0, data.indexOf("/") + 3);
var rate = data.substring(data.indexOf("/") + 3);
var json_data = "{" + "\n\tname: " + "final.pdf" + ",\n\tdate: " + date + ",\n\trate: " + rate + "\n}";
return json_data;
});
}
Turns out, if I just replace "options" with the base URL, it works. Strange. Problem solved. :)
Try this:
var request = require("request");
var fs = require("fs");
var cheerio = require("cheerio");
var path = "./final.pdf";
var url = "http://www2.nationalgrid.com/UK/Industry-information/System-charges/Electricity-transmission/Assistance-for-areas-with-high-distribution-costs/";
var links = [];
request(url, function(error, response, html) {
if(!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$(".txtLnk").each(function() {
links.push("http://www2.nationalgrid.com" + $(this).attr("href"));
});
var r = request(links[0]);
r.on('response', function (res) {
console.log(res.headers);
res.pipe(fs.createWriteStream(path));
});
}
});

Get signed_request in Node.js (Express) Facebook canvas app

is there any way how to get and parse signed_request in Node.js Facebook page tab app? I need to know page id and if user liked the page...
I did this a little while ago, and ended up writing a small library to do it. The original CoffeeScript can be found at https://gist.github.com/fbef51815ab6f062b51a#file_signed_request.coffee, here is a JavaScript translation:
var crypto = require('crypto');
SignedRequest = (function() {
function SignedRequest(secret, request) {
this.secret = secret;
this.request = request;
this.verify = this.verify.bind(this);
var parts = this.request.split('.');
this.encodedSignature = parts[0];
this.encoded = parts[1];
this.signature = this.base64decode(this.encodedSignature);
this.decoded = this.base64decode(this.encoded);
this.data = JSON.parse(this.decoded);
}
SignedRequest.prototype.verify = function() {
if (this.data.algorithm !== 'HMAC-SHA256') {
return false;
}
var hmac = crypto.createHmac('SHA256', this.secret);
hmac.update(this.encoded);
var result = hmac.digest('base64').replace(/\//g, '_').replace(/\+/g, '-').replace(/\=/g, '');
return result === this.encodedSignature;
};
SignedRequest.prototype.base64encode = function(data) {
return new Buffer(data, 'utf8').toString('base64').replace(/\//g, '_').replace(/\+/g, '-').replace(/\=/g, '');
};
SignedRequest.prototype.base64decode = function(data) {
while (data.length % 4 !== 0) {
data += '=';
}
data = data.replace(/-/g, '+').replace(/_/g, '/');
return new Buffer(data, 'base64').toString('utf-8');
};
return SignedRequest;
})();
module.exports = SignedRequest;
Which you can use like this:
var verifier = new SignedRequest(clientSecret, signedRequest);
verifier.verify() // whether or not the signed request verifies
verifier.data // the data from the signed request

restructure string in javascript

I have this string in which i need to re-structure using JavaScript.
Label=11121212&TopicArn=test&AWSAccountId.member.1=YYYYYYY&ActionName.member.1=createTopic&Action=AddPermission&Version=2010-03-31&AWSAccessKeyId=XXXXXXXXX&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp=2012-05-02T16%3A06%3A09.000Z&Signature=C3uIh%2Bz%2Fik
For this example, AWSAccessKeyId should be the first part of the string and label should be 2nd last. There are others as well, similar to this.
Expected output --AWSAccessKeyId=XXXXXXXXX&AWSAccountId.member.1=YYYYYYYYY&Action=AddPermission&ActionName.member.1=Publish&Label=ios-sns-permission-label&Signature=dEaNL0ibP5c7xyl4qXDPFPADW0meoUX9caKyUIx1wkk%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-05-02T00%3A51%3A23.965Z&TopicArn=arn%3Aaws%3Asns%3Aus-east-1%3A335750469596%3AiOSGoesWooooo-1335919882&Version=2010-03-31
Code that creates this incorrect string
exports.generatePayload = function(params, accessKeyId, secretKey, endpoint) {
var host = endpoint.replace(/.*:\/\//, "");
var payload = null;
var signer = new AWSV2Signer(accessKeyId, secretKey);
params = signer.sign(params, new Date(), {
"verb" : "POST",
"host" : host,
"uriPath" : "/"
});
var encodedParams = [];
for(var key in params) {
if(params[key] !== null) {
encodedParams.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
} else {
encodedParams.push(encodeURIComponent(key));
}
}
payload = encodedParams.join("&");
return payload;
}
I tried putting this in an array and restructure it but it didn't work for me.
Please advice how this can be done easily using JavaScript
exports.generatePayload = function(params, accessKeyId, secretKey, endpoint) {
var host = endpoint.replace(/.*:\/\//, "");
var payload = null;
var signer = new AWSV2Signer(accessKeyId, secretKey);
params = signer.sign(params, new Date(), {
"verb" : "POST",
"host" : host,
"uriPath" : "/"
});
var encodedParams = [];
if(params["AWSAccessKeyId"] != null)
{
encodedParams.push(encodeURIComponent("AWSAccessKeyId") + "=" + encodeURIComponent(params["AWSAccessKeyId"]));
}
if(params["AWSAccountId.member.1"] != null)
{
encodedParams.push(encodeURIComponent("AWSAccountId.member.1") + "=" + encodeURIComponent(params["AWSAccountId.member.1"]));
}
//other_ifs_for_param_keys_here
payload = encodedParams.join("&");
return payload;

Categories

Resources