HttpClient Angular POST fails with Google FCM Server, how do I fix? - node.js

I am able to successfully send FCM messages via a POST and HTTP v1 Firebase API to my app using Postman but when I use the same POST in Angular HttpRequest it fails:
Error
Here are my imports:
import { Injectable } from '#angular/core';
import { HttpClient , HttpResponse, HttpHeaders} from '#angular/common/http';
import { Observable } from 'rxjs';
import { map } from "rxjs/operators";
Here is my code in the service:
sendFCMMessage(accessToken : string, data: object) {
console.log('sendFCMMessage');
console.log(accessToken);
console.log(data);
const authString : string = 'Bearer '+ accessToken;
console.log(authString);
const url = 'https://fcm.googleapis.com/v1/projects/***-notifications/messages:send';
const httpOptions = { headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': authString
})};
const body =
{
"message":{
"token":"wwrwjeriwe8***",
"notification":{
"body":"The Knicks are winning!",
"title":"Sports App"
}
}
};
return this.http.post(url,body,httpOptions).pipe(map(res => res));
}
I then subscribe to the response and get the error pasted above. Does anyone know why I am getting this error and how to fix? I am able to send FCM messages perfectly in Postman using the same exact POST url, body and header.
Thanks

Http response status code 401 means unauthorized, so it seems that your bearer token header is not present in your request.
return this.http.post<any>(
url,
{
message: {
token: 'wwrwjeriwe8***',
notification: {
body: 'The Knicks are winning!',
title: 'Sports App',
},
},
},
{
headers: {
'Content-Type': 'application/json',
'Authorization': authString,
},
}
);

Related

Cannot send authorization bearer token throught axios

When I check in postman and sent the request to an api endpoint with the token works good:
But when I make the same request in expressjs to the api it sent me an unauthorized response:
Request:
try {
const response1 = await axios.get(`https://url/payment/pse/banks`,{headers: {
'Content-Type': 'application/json',
'Authorization':`Bearer ${token}`
}})
console.log("lista",response1.data);
} catch (error) {
console.log(error.response.data)
}
Response:
{
success: false,
titleResponse: 'Unauthorized.',
textResponse: 'Unauthorized.',
lastAction: '',
data: { token: '' }
}
What am I doing wrong?

Send Axios SOAP Request with `application/soap+xml` Content Type

Does anyone know how to send a SOAP request in axios with the content type application/soap+xml?
Currently, the data is being sent as an XML String, but the server I am posting to requires the content-type in header to be application/soap+xml. This causes the XML string to throw a 400 Bad Request error because the post body isn't actual XML, but is instead a string.
Unfortunately the server will not accept a content-type of text/xml.
Here is the snippet sending the request:
import { NtlmClient, NtlmCredentials } from 'axios-ntlm'
import { v4 as generateUuid } from 'uuid'
import { InvoiceData } from './pdf-invoice'
import { Configuration } from '#/configuration'
export const sendSoapPayload = async (orderData: InvoiceData) => {
try {
const credentials: NtlmCredentials = {
username: Configuration.NTLMUsername,
password: Configuration.NTLMPassword,
domain: Configuration.NTLMDomain,
}
const client = NtlmClient(credentials)
const soapPayload = createSoapPayload(orderData)
const resp = await client({
headers: {
'Content-Type': 'application/soap+xml',
},
url: Configuration.NTLMPostURL,
method: 'POST',
data: soapPayload,
})
console.log('RESP', resp.status, resp.data)
if (resp.status === 200) {
return true
}
return false
} catch (error) {
console.log(error.response)
console.log('Failed to send SOAP request.')
return false
}
}

a single script in node to get authToken from some xyz oath2 /token end point and call the following api. I have coded something like this below

// getToken.mjs
import axios from 'axios';
import qs from 'qs';
var data = qs.stringify({
'client_id': 'xxxx-xxx',
'client_secret': 'xxxx-xxx',
'scope': 'https://graph.microsoft.com/.default',
'grant_type': 'client_credentials'
});
const config = {
method: 'get',
url: 'https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded', },
data : data
};
export let accessToken = axios(config)
.then(function (response) {
console.log((response.data.access_token));
})
.catch(function (error) {
console.log(error);
});
--------- Calling the API in the second script -----
//get response.js
import axios from "axios";
import { accessToken } from "./getToken.mjs";
const config = {
method: 'get',
url: 'https://graph.microsoft.com/v1.0/me/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${accessToken}`,
}
};
export let data000 = axios(config).then(function (response) {
console.log(JSON.stringify(response.data));
}).catch(function (error) {
console.log(error);
});
console.log(data000);
On executing the > node response.js ... returns 401, client secret, and id is correct. However, I feel the accessToken is not getting imported and hence the error. How do I fix this?
Try to use POST method to get accessToken.
const config = {
method: 'post',
url: 'https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded', },
data : data
};

Issue sending a JSON object to Stripe

I am trying to send a JSON Object to Stripe, but I am always receiving an error from the response.
API resolved without sending a response for /api/ctrlpnl/products_submit, this may result in stalled requests.
{
error: {
code: 'parameter_unknown',
doc_url: 'https://stripe.com/docs/error-codes/parameter-unknown',
message: 'Received unknown parameter: {"name":"dasdas"}',
param: '{"name":"dasdas"}',
type: 'invalid_request_error'
}
}
My code is below:
import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27'
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
try {
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: JSON.stringify(name),
headers: {
'Accept': 'application/json',
"content-type": 'application/x-www-form-urlencoded',
Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
}).then((response) => {
return response.json();
}).then(data => {
console.log(data);
res.status(200).json(data)
})
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
The content-type of the fetch is correctly set to application/x-www-form-urlencoded, but the body contains a json. So Stripe is unable to parse the body parameters.
To fix that, you need to replace JSON.stringify by new URLSearchParams:
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: new URLSearchParams(name), // ← this will return "name=xxxx"
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
});
Note that I recommend using the Stripe library which is much simpler to use: stripe.products.create(name);, especially since you already included it in your code.

HTTP call to send data to server using Axios/Axios-retry

I have a JSON object that I wish to send to a server using the server's API key. I wish to have a retry count of 3 so that I can retry sending data if previous calls fail.
I am not sure whether to use 'axios-retry' or 'retry-axios'.
How do I configure the Content-Type in the header, and where do I add the API key and the data to be sent. My present code looks like this:
const axiosRetry = require('axios-retry');
axiosRetry(axios, { retries: 3 });
var data = { /*----My JSON Object----*/ };
axios.post('my url', data, {
headers: {
'Authorization': 'API_Key',
'Content-Type': 'application/json'
}
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});
Use axios instead, it is a Promise based HTTP client for the browser and node.js
var axios = require('axios')
axios.post(url,data, {
headers: {
'authorization': your_token,
'Accept' : 'application/json',
'Content-Type': 'application/json'
}
}).then(response => {
// return response;
}).catch((error) => {
//return error;
});

Resources