Send (POST) JSON object to RESTful API using UnityWebRequest - javascript

I am trying to connect my Unity app to a RESTful API I wrote using Javascript and MySQL. At the moment I am having an issue with the unity code which is calling one of my API endpoints - it seems like the Unity code is not connecting to the server at all.
Here is the server endpoint for reference:
app.post("/api/users/authenticate/", function(req, res) {
var queryString = `SELECT UserID, Password FROM UserAccount WHERE UserName = ?`;
console.log("test");
console.log(req.body.UserName);
console.log(req.body.Password);
connection.query(queryString, [req.body.UserName], function(err, resp) {
if (!resp[0]) {
res.send("ER_INCORRECT_USERNAME");
} else {
var string = JSON.stringify(resp);
var jsonResp = JSON.parse(string);
if (jsonResp[0].Password == req.body.Password) {
res.send(jsonResp[0].UserID.toString());
} else {
res.send("FAILURE_AUTHENTICATED");
}
}
});
connection.end;
});
You can see that this endpoint simply checks to see if the provided parameters are the same as the ones stored in the MySQL database so as to authenticate a player account. Take note of the console.log statements.
Here is the unity code that I am trying to use to POST to this endpoint:
public static class PlayerAccountsInterface
{
public static IEnumerator AuthenticatePlayer(String username, String password)
{
List<IMultipartFormSection> form = new List<IMultipartFormSection>();
form.Add(new MultipartFormDataSection("UserName", username));
form.Add(new MultipartFormDataSection("Password", password));
UnityWebRequest request = UnityWebRequest.Post(InterfaceTools.GetAccountsUrl("authenticate"), form);
request.SetRequestHeader("Accept", "application/json");
yield return request.Send();
}
}
The function InterfaceTools.GetAccountsUrl simply gets the IP address and URL of the server endpoint. This part is definitely correct. The server endpoint is also correct as I've tested it independently using POSTman.
When I run the unity code, no call is being made to the server endpoint. I know this because the three console.log() statements are not triggered.
What could be causing this issue?

Related

NodeJS Undefined JSON object

just posting a question as I have seen some other similar questions on here but none with a method that seemingly works for me.
I'm new to NodeJS and playing around with requesting data from an API. For my test here im just trying to pull ticker prices based on the input of a prompt from the user.
This works fine, however the object
This is the code I am using to try and make this work:
prompt.start();
prompt.get(['coin'], function (err, result) {
request({url: `https://min-api.cryptocompare.com/data/price?fsym=${result.coin}&tsyms=BTC,USD`, json:true}, function(err, res, json) {
if (err) {
throw err;
}
console.log(json);
var json = JSON.stringify(json);
var string2 = JSON.parse(json);
console.log(string2.btc_price);
console.log(json);
});
console.log('Retrieving: ' + result.coin);
});
The API request works, however it returns JSON that looks like this with my 3 console logs:
{ set_attributes: { btc_price: 1, usd_price: 15839.35 } }
undefined
{"set_attributes":{"btc_price":1,"usd_price":15839.35}} -- (Stringify'd response)
I want to be able to extract the btc_price & usd_price as variables, ive tried a few different methods and can't figure out where exactly im going wrong. Any help would be greatly appreciated!
Cheers,
J
When you attempt to extract the btc_price attribute, it's actually nested so your second console should read console.log(string2.set_attributes.btc_price);
axios has more stars on Github, more followers on Github and more forks.
Features
Make XMLHttpRequests from the browser
Make http requests from node.js
Supports the Promise API
Intercept request and response
Transform request and response data
Cancel requests
Automatic transforms for JSON data
Client side support for protecting against XSRF
Using async / await
// Make a request for a user with a given ID
var preload = null;
async function getPrice(symbol) {
preload = await axios.get('https://min-api.cryptocompare.com/data/price?fsym=${symbol}&tsyms=BTC,USD')
.then(function (response) {
preload = response.data;
})
.catch(function (error) {
console.log(error);
});
return `preload.BTC = ${preload.BTC}; preload.BTC = ${preload.BTC}`;
};
getPrice('ETH');
// return preload.BTC = 0.04689; preload.USD = 742.85

API post request body is empty when entering data in

I am trying to have a simple post function which uses bcrypt on the password passed, then stores the data in the database, however when I call the post request in postman I am getting an error. I add a console output to see what the body was showing up as, and it is just showing an empty object. Does anyone know what could be causing this? Below is my server code:
app.post('/createUser/', function(req, res) {
console.log("below is the req body");
console.log(req.body);
var pass = bcrypt.hashSync(req.body.password, salt);
var createPromise = interact.createUser(req.body.username,
pass,);
//did promise
createPromise.then(function(createResponse) {
if (createResponse.length > 0){
//this means that there was a user with that username in the db
res.json("yes");
}
else {
// otherwise, there wasn't anything in the database with this id
res.json("no");
}
}).catch(function(err) {
console.log(err);
console.log(req.body);
res.status(500).json(err);
});
});

node express.js Can't set headers after they are sent.'

I am new to both node and express so I figure I am doing something stupid.
Complete source code can be found at:
https://github.com/wa1gon/aclogGate/tree/master/server
logRouter.get("/loggate/v1/listall", function(req, res) {
let countStr = req.param('count');
let count: number;
if (!countStr) {
count = null;
} else {
count = Number.parseInt(countStr);
if (count == NaN) count = null;
}
acConn.listAllDatabase(count, (err: string, result: Array<LogGateResp>) => {
console.log("got list all data resp")
return res.json(result).end();
});
}
);
app.use('/', logRouter);
It works the first time though, but blows up the second.
listallDatabase connects to a network socket which gets XML database back, parses it and calls back with an JS object. Which in turn calls res.json.
Suggestions?
Remove the end() after res.json().
res.josn() send the response to frontend and end() try to send the response again.
That why you are getting the error. Because node.js don't allow the API to send response twice. Either use res.end() or res.json().

Http authorization with node.js

My former server.js is like:
After running the server I could see my index.html
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname)).listen(5000, '192.168.xx.xx', function(){
console.log('Server running on 5000');
});
I want to create http login and password to secure the website, so I found online the information of http module: if I put right login and password, I could see congratulations message:
var http = require('http');
var server = http.createServer(function(req, res) {
// console.log(req); // debug dump the request
// If they pass in a basic auth credential it'll be in a header called "Authorization" (note NodeJS lowercases the names of headers in its request object)
var auth = req.headers['authorization']; // auth is in base64(username:password) so we need to decode the base64
console.log("Authorization Header is: ", auth);
if(!auth) { // No Authorization header was passed in so it's the first time the browser hit us
// Sending a 401 will require authentication, we need to send the 'WWW-Authenticate' to tell them the sort of authentication to use
// Basic auth is quite literally the easiest and least secure, it simply gives back base64( username + ":" + password ) from the browser
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="Secure Area"');
res.end('<html><body>Need authorization</body></html>');
}
else if(auth) { // The Authorization was passed in so now we validate it
var tmp = auth.split(' '); // Split on a space, the original auth looks like "Basic Y2hhcmxlczoxMjM0NQ==" and we need the 2nd part
var buf = new Buffer(tmp[1], 'base64'); // create a buffer and tell it the data coming in is base64
var plain_auth = buf.toString(); // read it back out as a string
console.log("Decoded Authorization ", plain_auth);
// At this point plain_auth = "username:password"
var creds = plain_auth.split(':'); // split on a ':'
var username = creds[0];
var password = creds[1];
if((username == 'admin') && (password == 'admin')) { // Is the username/password correct?
res.statusCode = 200; // OK
res.end('<html><body>Congratulations, feel free to explre!</body></html>');
}
else {
res.statusCode = 401; // Force them to retry authentication
res.setHeader('WWW-Authenticate', 'Basic realm="Secure Area"');
// res.statusCode = 403; // or alternatively just reject them altogether with a 403 Forbidden
res.end('<html><body>You shall not pass</body></html>');
}
}
});
server.listen(5000, function() { console.log("Server Listening on http://localhost:5000/"); });
I am new to nodejs, I want to know how to combine this 2 js? In order to realize my function of adding authorization to my web.
Could I do something to show my index instead of showing congratulation message after putting the login and password?
Thanks a lot.
In order to show HTML page instead of congratulation message, you can follow these steps:
Get request path by req.url, such as / or /introduction.html.
According to the above path, read the corresponding HTML file in server disk, using fs.readFile().
Return HTML file content to browser if the read is successful. Otherwise, return 404 error page.
Here is some example code for above steps:
if((username == 'admin') && (password == 'admin')) { // Is the username/password correct?
res.statusCode = 200; // OK
// res.end('<html><body>Congratulations, feel free to explre!</body></html>');
var requestURL = req.url; // e.g. / or /a or /a.html
var requestFilePath = getFilePathFromRequestURL(requestURL); // you need to implement this logic yourself, such as "/" mapping to "./index.html"
fs.readFile(requestFilePath, function(error, data) {
if (error) {
res.statusCode = 404;
res.write('File not found.');
} else {
res.statusCode = 200;
res.write(data);
}
res.end();
});
}
However, unless you want to write some low-level node.js code to better understand this language, I highly recommend using node.js web framework such as Express. Serve HTTP request using low-level node.js would be tedious, especially in production code.
Also, please note that using WWW-Authenticate Basic for authentication is neither secure nor user-friendly. You need some other way to implement authentication, such as JSON Web Tokens

Request for api not working properly

I'm making a request but it doesn't seem to work. If I copy code into my browser it works good, but in my console it shows up this :
{
"status" : "success",
"data" : {
"error_message" : "API access enabled, but unable to verify two-factor authentication code. If you need help with this, please contact support#bitskins.com."
}
}
What am I doing wrong? It's based on two-factor authentication that as I said works good while printing the url itself and when i'm copying it into my browser.
var url = 'https://bitskins.com/api/v1/get_item_price/?api_key='+bitskins.apikey+'&code='+bitskins.code+'&names='+encodeURIComponent(items[i].market_hash_name)+'&delimiter=!END!';
console.log(url);
request(url, function (error, response, body) {
if (!error) {
console.log(body)
}
});
In case you want, here is my api key module to generating it (api key deleted for security)
var TOTP = require('onceler').TOTP;
//Create a TOTP object with your secret
var totp = new TOTP('deleted');
// print out a code that's valid right now
// console.log(totp.now());
var code = totp.now();
module.exports = {
code: code,
apikey: 'deleted'
}
Founder of BitSkins, Inc. here. You need to have the following:
1) Your API Key
2) Your Secure Access Secret
You see the Secret when you enable Secure Access. If you do not have this, just disable/re-enable Secure Access and note the Secret down. The TOTP code you generate is with that Secret. Generate the TOTP code right before every API call and you'll be fine.
I think it should work. For me it works fine.
var API_KEY = ''; //It is very important
var SECRET_KEY = ''; //It is very important
var totp = new TOTP(SECRET_KEY);
var code = totp.now();
var options = {
url: 'https://bitskins.com/api/v1/get_item_price',
form: {
'api_key': API_KEY,
'names': 'Tec-9%20%7C%20Sandstorm%20(Minimal%20Wear)',
'delimiter': '!END!',
'code': code
}
};
function callback(error, response, body) {
if (!error) {
var info = JSON.parse(body);
console.log(info);
}
}
request.post(options, callback);
What npm package do you use to create 2FA code? I'm using "onceler" from example but I think it creates wrond codes. Here is my code:
var API_KEY = ''; //correct key from settings page
var SECRET_KEY = ''; // correct key which I copied from form with QR code.
var totp = new TOTP("SECRET_KEY");
var code = totp.now();
This code doesn't equal code which I can see in my mobile device and with this code I get error message like in author's question. But if I put code from my mobile in programm code - it works fine. So what package should I use to get correct codes?

Categories