Narro API:: message: 'Unauthorized' - javascript

I was trying to work with Narro API and MEAN stack. I have some text articles. I want to convert my text data to audio. From the requirements, it should use Narro.co for audio conversion. From their documentation, I started with authentication.
Here is the code,
var request = require("request");
var options = {
method: 'GET',
url: 'https://www.narro.co/api/v1',
headers: {
authorization: 'Bearer <access_token>'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
We can generate the clientId and clientSecret from the Narro developer account.
The ClientId(sample) :
921edefq-540y-4g75-be2c-2ade450dc503
The clientSecret(sample):
a904efd2-a362-4cc5-80qe-262b24728b47743e244e-e39c-44e7-a479-3f0bt3445245
But it is not working.
I always end up with -
{ errors: [ { message: 'Unauthorized' } ] }
If it is not the right method, Please suggest me the best way to use Narro API with authentication.

You need to follow proper OAuth 2.0 flows.It would seem you want to use the Client Credential flow for your purposes, if you're not doing actions on behalf of a user.
I hope the ClientID and Secret there aren't actually yours.
Their own documentation page links to https://oauth.net/2/ which is where you can learn about the different flows, how to request a Bearer token, and how to then use that token to access the API endpoints. (Basically, read the docs...)

Related

Clash Royale Node Fetch with Key

Im trying to make a discord bot where if you type -cr into the chat, it takes the Arguments of the user (Being the Clash Royale Player's player tag) and would then use the package node-fetch to receive data with my specified endpoint. I am constantly running into the error of { reason: 'accessDenied', message: 'Invalid authorization' }. Im rather new to this stuff, especially API's, but im hoping to access certain data which I can decide later on (Which I know how to do). My code is :
const fetch = require('node-fetch')
module.exports = {
name: 'clash',
aliases: ['cr', 'clashroyale'],
category: 'This',
utilisation: '{prefix}clash',
async execute(client, message) {
var msgArgs = message.content.slice(this.name.length + 1)
var endpoint = `/players/${msgArgs}`
var url = `https://api.clashroyale.com/v1`
var token = `hidingmytoken`
fetch(url + endpoint, {
method: 'POST',
headers: {
"Authorization": token
}
}).then(data => data.json()).then(json => {
console.log(json)
})
},
};
The message parts with msgArgs and discord sides all work but fetching that clash Royale API is a big hurdle for me. The API for Clash Royale can be found here https://developer.clashroyale.com/#/documentation and Im just generally stuck on this whole concept. Im using version 2.6.6 of node-fetch so I can use the require() method which should work if that does matter. In general, how can I pass my token properly to receive that API data?
Since the Clash Royale API uses bearer authentication, you need to specify that it will be a bearer token.
headers: {
'Authorization': `Bearer ${token}`
}
I've implemented the following functionality. The code is written in GO but you can copy the logic and translate into your language.
The library have the following functionality:
Login
Token generation
Token list
Token delete
https://github.com/alessiosavi/GoClashRoyale/blob/master/api/auth.go

How to store access token and pass to next api call in javascript fetch

I was just wondering if someone could help me figure this out. My code to get the access token is:
const inputBody = 'client_id=00000000-0000-0000-0000-000000000001&secret=mySecretPassword';
const headers = {
'Content-Type':'application/x-www-form-urlencoded',
};
fetch('https://api.replicastudios.com/auth',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
I then need to include the access token received from the first call in order to insert it below.
const headers = {
'Authorization':'Bearer {token}'
};
fetch('https://api.replicastudios.com/voice',
{
method: 'GET',
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
});
What is the best way to save the access token and insert it into the second request?
Please, and one more time, please don't store users security tokens in session storage, local storage, cookies (by yourself, let browser do it securely for you), etc.
Browsers have pretty awesome way of handling those security sensitive stuff, and those ways are preventing session hijacking through XSS and bunch of other stuff.
Proper way of doing things:
On the frontend you call your login (or in your case) auth route, and from the backend instead of sending your security token in body you need to set it in the secure cookie. One of the common ways to do it with Node+Express is like this:
res.status(200)
.cookie('auth_cookie', token, { httpOnly: true, maxAge: 86400 * 1000, sameSite: 'none', secure: true})
.json({ success: true, message });
This was one example of it, you should learn what all those arguments do here: https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector/Cookies
And on the last part, you dont need to manually include those cookies with each other request after that, if you are using Axios you can just put { withCredentials: true } and it's gonna automatically include those secured tokens in the cookie part of your request. There is a good thread already on that here: Make Axios send cookies in its requests automatically
I understand that this can seem as much work but it will make web safe(er) and it promotes good practices.
If your code is in a browser which it seems like it is, you could save the access token to session storage for use in future calls. When the tab is closed, session storage will be cleared.
const inputBody = 'client_id=00000000-0000-0000-0000-000000000001&secret=mySecretPassword';
const headers = {
'Content-Type':'application/x-www-form-urlencoded',
};
fetch('https://api.replicastudios.com/auth',
{
method: 'POST',
body: inputBody,
headers: headers
})
.then(function(res) {
return res.json();
}).then(function(body) {
console.log(body);
// NEW CODE
// body.access_token is my guess, you might have to change this
// based on the response
window.sessionStorage.setItem('access_token', body.access_token)
});
Then you can get the access token using:
window.sessionStorage.getItem('access_token')

Get Images from IP Cam url with http authentification

Hi I try to place snapshots of my CCTV Cam on my Webpage/HTML page (all localy).
But the Problem is the HTTP Authentification.
<img id="img1" border="0" src="http://admin:admin#192.168.178.41/tmpfs/auto.jpg">
This solution isn't possible because Chrome doesn't allow credentials in the URL anymore for security reasons.
Without the credentials I get a Error 401 obviously.
I tried it with an xmlHttpRequest, but the problem was the CORS which I can't activate on the ServerSide of the camera, from where I want to get the images. I already tried to disable the http authentification in the cam but the interface doesn't allows it. I don't care about the security aspect, because the cam is only used in a local network, which is protected. I also tried something with node.js
var request = require('request');
var options = {
url: 'http://192.168.178.41/tmpfs/auto.jpg',
auth: {
username: 'admin',
password: 'admin'
}
};
request.get(options);
console.log(request.get(options));
Sry, I am not that expirienced with Node.js and hope you can help me with my problem.
you should be able to do this with nodeJs , you're sending the request but you're not doing anything with the result, it's available in the callback, try this :
const auth = 'Basic ' + Buffer.from(username + ':' password).toString('base64');
const options = {
url : 'http://192.168.178.41/tmpfs/auto.jpg',
headers : {
"Authorization" : auth
}
}
request.get(options, (error, response, body) => {
console.log(body); // there's your image
});
you can always put the auth credentials in the url directly :
const options = {
url : 'http://admin:admin#192.168.178.41/tmpfs/auto.jpg'
}
request.get(options, (error, response, body) => {
console.log(body); // there's your image
});
You could do it easier in this case, cause the ip cam handes authentication with parameters you could easily give the path with the following flags: ?usr=admin&pwd=admin
The result would be:
<img id="img1" border="0" src="http://192.168.178.41/tmpfs/auto.jpg?usr=admin&pwd=admin">
Sidenote, "snap.jpg" delivers the full image.

No authorization token was found when res.redirect

I have two applications, both on Nodejs. One front-end and other back-end.
My back-end app is protected with token access using express-jwt and jsonwebtoken middlewares.
My problem is: I am making a request from front-end to back-end passing the token on header, back-end accepts the request and respond properly. Then in the front-end I redirect the response to an specific page (res.redirect('/')), in that moment I get the error UnauthorizedError: No authorization token was found
My front-end request:
/* Authentication */
router.post('/', function(req, res, next) {
// request login service
request({
uri: env.getUrl() + "/user",
method: 'POST',
timeout: 10000,
headers: {
'Authorization': 'Bearer '.concat(global.token)
},
form: { login : req.body.login, pwd : req.body.pwd }
}, function(error, response, body){
if(error) {
logger.error(error);
res.render("error", {message: "Error getting user" });
}
else {
if(body){
req.session.usuario = JSON.parse(body);
res.redirect("/");
} else {
res.render("login", {message: "Login Failed" });
}
}
});
});
I don't know why this happen. Could you help me?
Thanks in advance.
A redirect (via res.redirect) issues a new HTTP request. This means that the Authorization header is empty. This results in the UnauthorizedError error.
To fix this, you have two options:
1. Pass the token in the URI
You can issue the redirect with the token passed in the URL in this way:
res.redirect("/?access_token=" + global.token);
2. Set the header before the redirect
You can set the 'Authorization' header before making the redirect request:
req.session.access_token = global.token;
Problem found.
Anytime the my front-end app makes a request to the back-end side (api) the user logged in front-end is validated against back-end and so the fron-end's session is updated as well. Which means that every request is actually two requests:
One as the real request the app is doing.
The request validating the user logged on front-end in order to be sure that user exists.
This update (second point) was made without providing a token.

Get Dropbox OAuth Token from Code via request.js Fails; Equivalent curl Works

I'm trying to exchange my Dropbox oauth code for a token as per the http api documentation.
When I perform the command with curl thusly:
curl https://api.dropbox.com/1/oauth2/token \
-d code=<authorization code> \
-d grant_type=authorization_code \
-u <app key>:<app secret>
everything works fine, and I am returned my bearer token. Unfortunately, what
seems to be equivalent code written in node.js with the request module fails.
var request = require("request");
var config = require("./config.json");
request({
url: "https://api.dropboxapi.com/1/oauth2/token",
method: "POST",
auth: {
user: config.client_id,
pass: config.client_secret
},
json: {
code: config.code,
grant_type: "authorization_code"
}
}, function(err, resp, body) {
if (err) throw err;
console.log(body);
});
logs:
{ error_description: 'missing required field "grant_type"',
error: 'invalid_request' }
The docs
say that in the event of a 400 error (which this is), I have:
Bad input parameter. Error message should indicate which one and why.
Though as can be seen from the above code, the grant_type is being
specified.
Notably the docs give a second option to authenticate, though this too fails,
albeit with a different message:
Description (abridged)
Calls to /oauth2/token need to be authenticated using the apps's key and secret. These can either be passed as POST parameters (see parameters below) or via HTTP basic authentication. If basic authentication is used, the app key should be provided as the username, and the app secret should be provided as the password.
Params
code String The code acquired by directing users to /oauth2/authorize?response_type=code.
grant_type String The grant type, which must be authorization_code.
client_id String If credentials are passed in POST parameters, this parameter should be present and should be the app's key (found in the App Console).
client_secret String If credentials are passed in POST parameters, this parameter should be present and should be the app's secret.
redirect_uri String Only used to validate that it matches the original /oauth2/authorize, not used to redirect again.
My attempt at the alternate authentication procedure:
var request = require("request");
var config = require("./config.json");
request({
url: "https://api.dropboxapi.com/1/oauth2/token",
method: "POST",
json: {
code: config.code,
grant_type: "authorization_code",
client_id: config.client_id,
client_secret: config.client_secret
}
}, function(err, resp, body) {
if (err) throw err;
console.log(body);
});
logs:
{ error_description: 'No auth function available for given request',
error: 'invalid_request' }
In case the full response from dropbox for either of my two request attemps would be helpful I posted it on pastebin.
I am not including the redirect_uri as I did not use it as part of the code
flow. This is permitted as per the docs. In any case, I don't have any problems
when ommitting it in the curl command which does succeed.
Considering that my API call succeeds when sent through curl, I'm clearly doing
something wrong with my js request. What can I do to get the bearer token I
expect?
It looks like in your curl command, you're sending a form-encoded POST request (which is what OAuth uses), but in your Node.js code, you're sending a JSON-encoded request.
Try form: { ... } instead of json: { ... }.

Categories