Error 401 (Unauthorized) When making REST calls using Axios with JWT headers included - jwt

I'm developing a small react node application with JWT passport for authentication. I've tested all the endpoint through postman(by passing token with authorization header) and they are working properly.
This is the call im making from the front-end
export const getUsersDetails=()=>{
console.log( localStorage.getItem('jwtToken'));
return (dispatch) => {
return axios.get('http://localhost:3030/users',
{ headers: { 'Authorization': localStorage.getItem('jwtToken') } }
).then((data)=>{
console.log('data comming',data);
dispatch(getUsersData(data));
}).catch((error)=>{
console.log('error comming',error);
dispatch(errorgetUsersData(error));
});
};
}
I have enable CORS by using the the CORS module. this is the how the network calls looks like from the browser
the authorization header looks like
authorization:[object Object], eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.....
Should this be like authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.....
Is this the reason why im facing this issue? How to overcome this?

I was able to solve a similar issue on a MERN stack, by configuring axios globally in the react application, by adding Bearer and one space, in front of the token that is assigned globally.
axios.defaults.headers.common['Authorization'] =Bearer ${token};
initially, it was without Bearer and i kept getting a 401 status code.
axios.defaults.headers.common['Authorization'] = token;

When you want authorization in your app, it depends on how you have done your back end. If everything is ok trough postman, show how your headers in postman look when you have tasted. I use xsrf token and here is how my request header look:
{headers:
{"Access-Control-Allow-Headers" : "*",
"X-XSRF-TOKEN": this.$cookie.get('XSRF-TOKEN')}
}
Maybe you should just put "Access-Control-Allow-Headers" : "*"

Related

Postman request works but Axios request fails

I am trying to perform a request which is successful in Postman:
https://ad2zu2nol06:827xhabn112#domain:1011/index.php?action=/v1/installations/7/plugins
This GET request works fine within Postman, however, when I use Axios to create the same request:
let response = await axios.get(url, {}, {
auth: {
username: 'ad2zu2nol06',
password: '827xhabn112;'
}
});
I get a 401 not authorized, I've tried everything and cannot figure it out, there is no CORS policy issues at all.
I don't know what else to do, totally lost.

Facebook Webhook Test Button not working as expected

I have successfully added my callback url in my webhooks setup. At that time, the callback url was called successfully with proper logs and everything in the server. But when I click on the TEST button for the respective name (leadgen in this case), nothing AT ALL is being received by the server when in fact it should at least log the very first line. Note that I am using post and get.
Additional note: for NetSuite experienced developers, I am using a suitelet as the callback url for the webhook.
Thanks.
Suitelets that are available externally without login will only work if the User-Agent header in the request mimics a browser. See for example SuiteAnswers # 38695.
I ran into a similar issue, and the workaround was to proxy the request using a Google Cloud Function that simply rewrote the User Agent:
const request = require('request');
exports.webhook = (req, res) => {
request.post(
{
url: process.env.NETSUITE_SUITELET_URL,
body: req.body,
json: true,
headers: {
'User-Agent': 'Mozilla/5',
Authorization: req.headers['authorization'],
},
},
function(error, response, body) {
res.send(body);
}
);
};

Securing a restful API verifying clients with JWT

I have a RESTful API using JWT for authentication purposes. The first call I receive from a client is the /login call, with the following payload (no headers)
{
"username" : xxxx,
"password": wwww
}
The server verifies if the user is registered and then returns a signed JWT to the client in order to be received in the next calls.
I wonder if this is secure enough. I don't check anywhere if the client sends me a client id / client secret (like in OAuth) so I cannot verify if this call is from my webapp / apps or if it is an external client which I don't know about. I want to know if it makes sense to implement this behavior using JWT and how to implement it.
(I know how to do it with OAuth2 but I don't want to move now from JWT authentication)
Thank you!
If I understood you correctly, you should create a function somewhat similar to this:
function verify(req, res, next) {
const token = req.header('x-auth-token');
if (!token) {
return res.status(401).json({
msg: 'No token, auth denied'
});
}
try {
const decoded = jwt.verify(token, config.get(YOUR_SECRET_GOES_HERE));
req.user = decoded.user;
next();
} catch (err) {
res.status(401).json({
msg: 'Token is not valid'
});
}
}
For all secured API endpoints you should apply it like this:
router.get('/anyuserinfo', verify, (req, res) => ...
And that is it. The function will send 401 response if no token is provided.
I think I found another Stackoverflow question that answers mine:
JWT (Json Web Token) Audience "aud" versus Client_Id - What's the difference?
In a nutshell, client_id and client_secret should be sent on headers to the server to be validated before sending a new JWT token.

Authorization header malformed WP JWT Authentication for WP REST API

I have managed to get the token using user and pass and now I am passing the token using this ajax call in order to create a new post , like this :
$.ajax({
url: "http://apibind.com/wp/wp-json/wp/v2/posts",
type: "POST",
headers: { "Authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
success: function (data) {
console.log(data);
},
error:function(data){
console.log(data);
}
});
and I get this error : Authorization header malformed . Anyone knows what is wrong with the header?
simple misstake : Bearer instead of Basic (I'm using a token based authorization)
Remove the JWT related plugins from your WordPress(for my case , it's "Simple JWT Login"). They help if you are developing mobile apps for site but they interfere with the rest api call.

Current method to get new access token from refresh token

I see some questions about this with solutions that seem to be deprecated in the Google APIs Node.js Client OAuth API (e.g., this and this).
There's no documentation I can see regarding using the refresh token to get a new access token (docs section). In an issue from early 2017, someone mentions getting off the oauth2Client.credentials property, but it looks like that's within a call to one of the other APIs wrapped in the package.
In my use case, I'm querying the Google My Business (GMB) API, which is not wrapped in there, but I'm using the OAuth piece of this package to authenticate and get my tokens.
My request to the GMB API (using the request-promise module), looks something like this:
function getLocations () {
return request({
method: 'POST',
uri: `${gmbApiRoot}/accounts/${acct}/locations:batchGet`,
headers: {
Authorization: `OAuth ${gmbAccessToken}`
}
})
.then(function (response) {
console.log(response);
})
.catch(function (err) {
// ...
});
}
I don't think I can pass the oauth2Client into the headers for authorization like in the issue response. Is there a way to directly request a new access_token given that I have my refresh token cached in my app?
Update: Solved! Thanks to Justin for the help. Here's what my working code is looking like:
oauth2Client.setCredentials({
refresh_token: storedRefreshToken
});
return oauth2Client.refreshAccessToken()
.then(function (res) {
if (!res.tokens && !res.credentials) {
throw Error('No access token returned.');
}
const tokens = res.tokens || res.credentials;
// Runs my project-level function to store the tokens.
return setTokens(tokens);
});
If you have an existing oauth2 client, all you need to do is call setCredentials:
oauth2client.setCredentials({
refresh_token: 'REFRESH_TOKEN_YALL'
});
On the next call that goes through the client, it will automatically detect there is no access token, notice the refresh token, and go snag a new access token along with it's expiration date. I outlined some docs and code around this in the issue you opened up on GitHub :P
https://github.com/google/google-api-nodejs-client/pull/1160/files
Hope this helps!
I wanted to add in my learning, to the community, in case it helps anyone out there struggling with this too. The above answers were correct, but I discovered one other attribute.
Namely, I was calling my credentials like this:
oAuth2Client.setCredentials(JSON.parse(authResults));
my authResults, is defined as this:
const authResults = fs.readFileSync(TOKEN_PATH);
This results in several fields being filled in to the results variable:
[
'access_token',
'refresh_token',
'scope',
'token_type',
'expiry_date'
]
Now here's the nuance...if the access_token AND the refresh_token are both given to the setCredentials call, the refresh-token is ignored. Changing to the above answer, where I send in only the refresh token:
oAuth2Client.setCredentials({ refresh_token: creds['refresh_token'] });
Worked like a champ! Hope this finds its way and helps someone else.