Unexpected Token with Google API and Node.js - node.js

I have the below method that uses #types/google-tap to authenticate via google. Below is my client code:`
LoginWithGoogle(credentials: string): Observable<any> {
console.warn('it broke here')
const header = new HttpHeaders().set('Content-type', 'application/json');
return this.httpClient.post(this.path + "/loginwithgoogle", JSON.stringify(credentials), { headers: header });
}
}`
Then I have the server which is on node.js:
app.use(cors());
app.use(bodyparser.json());
app.use(express.json())
app.use(express.urlencoded())
app.post('/loginwithgoogle', function (req, response) {
const decode = jwt.verify(req.body.token, 'secret here');
res.json({
login: true,
data: decode
});
});
When the api is called, I get the below error:
SyntaxError: Unexpected token " in JSON at position 0
at JSON.parse ()
at createStrictSyntaxError (C:\Repo\Sites\voyazair\voyazair\server\node_modules\body-parser\lib\types\json.js:160:10)
at parse (C:\Repo\Sites\voyazair\voyazair\server\node_modules\body-parser\lib\types\json.js:83:15)
at C:\Repo\Sites\voyazair\voyazair\server\node_modules\body-parser\lib\read.js:128:18
Any Idea what I am doing wrong? I looked up for some solution that suggested JSON.Parse/JSON.stringify but that did not work for me.

Related

Slack OAuth HTTP Post Request returns "undefined" access token

I'm using the following code in a simple slash command app to handle OAuth for public distribution of my app:
const express = require("express");
const bodyParser = require("body-parser");
const fetch = require("node-fetch")
require('dotenv').config();
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
// App installation handling
app.get("/auth", async (req, res) => {
if (!req.query.code) {
console.log("Access denied!");
return;
}
var data = {form: {
client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET,
code: req.query.code,
redirect_uri: "https://6c0c-35-20-201-50.ngrok.io/auth"
}};
console.log(req.query.code);
// Send received code back to Slack and get Oauth2 access token
const config = {
method: "POST",
body: data,
headers: {'Content-type': 'application/x-www-form-urlencoded'}
};
console.log("We got something!");
try {
const slack_oauth_response = await fetch("https://slack.com/api/oauth.v2.access", config);
console.log("Access token granted!");
console.log(JSON.stringify(slack_oauth_response.access_token));
} catch (e) {
console.error(e);
}
res.sendStatus(200);
})
When I try using the Add to Slack button, I get a timeout error. My log results will look like this:
PS D:\Documents\SlackRegApp> node local_testing.js
1007612862405.3292595223126.481b3e25d2c29dc80af7dc21bcb84a8bc19c28ddec155a429c6651105903902f
We got something!
Access token granted!
undefined // where the access token should be
If I go ahead and just log the entirety of slack_oauth_response, it looks like this:
{"size":0, "timeout":0}
When I try to install the app via cURL, it works, like below:
curl -F code=1007612862405.3292595223126.481b3e25d2c29dc80af7dc21bcb84a8bc19c28ddec155a429c6651105903902f -F client_id=**SLACK_CLIENT_ID** -F client_secret=**SLACK_CLIENT_SECRET** https://slack.com/api/oauth.v2.access
Hoping for some help here, thanks!
I just used the Slack WebClient API to access the oauth.v2.access method instead of trying to make my own HTTP request.

Json response returning HTML in nodejs/react page

I'm new react and nodejs and full stack development in general. I'm trying to make a login page in nodejs/react/mysql. Right now, I'm just trying to do get request for the main login page. I think I'm struggling with connecting the front and backend and the moment.
Nodejs app.js:
const express = require('express');
const bodyparser = require('body-parser');
const cors = require('cors');
const app = express();
const mysql = require('mysql');
let connection = mysql.createConnection({
//Connection is encrypted for security reasons.
host: '***********',
user: '***********t',
password: '***********',
database: '***********'
});
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
app.listen(3001, () => { console.log('running on port 3001'); });
app.use(cors());
app.use(express.json()); a
app.use(bodyparser.urlencoded({extended: true}));
app.get('/', (req, res) => { res.send('respond with a resource'); });
componentDidMount() react code/fetch request:
componentDidMount() {
// GET request using fetch with error handling
fetch('/')
.then(async response => {
const data = await response.text();
// console.log(data);
console.log('test',data);
// check for error response
if (!response.ok) {
// get error message from body or default to response statusText
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
this.setState({ totalReactPackages: data.total })
})
.catch(error => {
this.setState({ errorMessage: error.toString() });
console.error('There was an error!', error);
});
}
My sql connection works fine, I think it's an issues connecting the front end and backend. Changing following line:.
const data = await response.text();
to:
const data = await response.json();
Returns the following error:
There was an error! SyntaxError: Unexpected token < in JSON at position 0
This is the html it returns in the following screenshot:
Once I figure out how to connect the front end and backend the rest of the project should be easyish to do. The react UI work and my SQl connection works fine. Any help would be greatly appreciated.
You're currently fetching data from the primary site, not the Node.js site you've created.
You should change the fetch to:
fetch('http://localhost:3001')
Additional information
The response you are sending from the backend isn't JSON:
res.send('respond with a resource');
To send JSON, you should use:
res.json({ message: "respond with a resource" });
Then you'll be able to use:
const data = await response.json();
And access the data via:
const message = data.message;
For me it worked just by appending "Https://" to the beginning of the API url.
fetch(`https://api.openweathermap.org/data/2.5/weather?q=${CITY_NAME}&appid=${API_KEY}`)
It took me days and 10s of articles/SO threads to figure out that when doing dev on your local machine the fetch request gets routed to local html document.

Express server not working with the ionic frontend

I am trying to send HTTP POST request from the frontend to the backend. I first tried the backend with postman and it worked fine. However, when I tried it with the frontend it did not respond. There are no errors or warnings, it just does not post anything to the database and does not return a response. Here is my HTTP request from the frontend:
public addReg(UserOb) {
console.log("callingaddReg");
var headers = new Headers();
headers.append("content-type", "application/json");
console.log("headers appended");
return this.http
.post("http://localhost:3000/api/auth/register", UserOb)
.map(res => {
return res;
});
}
The above method logs headers appended in the console.
The backend method which handles the request is as follows:
router.post("/auth/register", isNotAuthenticated, authCtrl.register);
Here is the isNotAuthenticated middleware:
var isNotAuthenticated = function(req, res, next) {
// Check that the request doesn't have the JWT in the authorization header
var token = req.headers["authorization"];
if (token) {
return res.status(403).json({
error: null,
msg: "You are already logged in.",
data: null
});
}
next();
};
The end point location is in the index.js file
api
routes
index.js
Here is the URL to my monogdb: 'mongodb://localhost:27017/waterProject'

Getting exception on webhook from Stripe

I'm trying to set up a webhook from Stripe to handle the payment_intent.succeeded event, but I get an exception. This is my code from the Node backend (I have extracted all the relevant parts I hope. Let me know if anything else is needed):
const stripeWebHookSecret = 'whsec_WA0Rh4vAD3z0rMWy4kv2p6XXXXXXXXXX';
import express from 'express';
const app = express();
app.use(bodyParser.urlencoded({ extended:true }));
app.use(bodyParser.json());
app.use(session({ <some params here> }));
const openRouter = express.Router();
registerOpenPaymentRoutes(openRouter);
app.use('/open', openRouter);
And the implementation of registerOpenPaymentRoutes looks like this:
export const registerOpenPaymentRoutes = (router) => {
router.post('/payment/intent/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
let signature = req.headers['stripe-signature'];
try {
let event = stripe.webhooks.constructEvent(req.body, signature, stripeWebHookSecret);
switch(event.type){
case 'payment_intent.succeeded':
let intent = event.data.object;
res.json({ message: 'Everything went smooth!', intent });
default:
res.status(400).json({ error: 'Event type not supported' });
}
}
catch (error){
res.status(400).json({ message: `Wrong signature`, signature, body: req.body, error });
}
});
}
So far so good.When I fire a test webhook event from the Stripe dashboard, I hit the endpoint, but get the result from the catch block. The error message is as follows:
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing"
I'm returning the signature with the error message as well as you see above, and the signature looks like this:
"t=1557911017,v1=bebf499bcb35198b8bfaf22a68b8879574298f9f424e57ef292752e3ce21914d,v0=23402bb405bfd6bd2a13c310cfecda7ae1905609923d801fa4e8b872a4f82894"
As far as I understand from the documentation, what is needed to get the raw request body as mentioned are the bodyParser.raw({type: 'application/json'})argument to the router that I already have there.
Can anyone see the missing part?
It's because you've already set your express app to use the bodyParser.json() middleware, which clashes with the bodyParser.raw() middleware you set up in your webhook route.
If you remove the app.use(bodyParser.json()); line your webhooks will work as intended, but then the rest of your routes won't have a parsed body, which isn't ideal.
I suggest adding a custom middleware to choose the bodyParser version based on route. Something like:
// only use the raw bodyParser for webhooks
app.use((req, res, next) => {
if (req.originalUrl === '/payment/intent/webhook') {
next();
} else {
bodyParser.json()(req, res, next);
}
});
Then explicitly use the bodyParser.raw() middleware on the webhook routes.
I came up with the very same problem, the answer above gave me an idea on how to solve it but didn't make the gig for me, so thanks for pointing me in the right direction.
I share the way it worked for me to bring the body raw without too much effort
I just add in my index.js after
app.use(bodyParser.urlencoded({ extended: false }));
this
app.use(
bodyParser.json({
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
},
})
);
app.use(
bodyParser.urlencoded({
extended: false,
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
},
})
);
And then on the function where I needed a raw body I used:
router.post("/webhook",express.raw({ type: "application/json" }),async (req, res) => {
const sig = req.headers["stripe-signature"];
const body = req.rawBody; //here I got the raw body
});
And that was enough to pass the (in this case) stripe validation
Hope to be helpful to somebody!
Have a great coding!

NodeJS http post data empty

I am not able to get the data in the http post method of express nodejs.I am posting data from angular2. When i inspect in the network section of chrome, the payload is visible but the same data is received blank at app.post method.Please help me.
angular2 code
this.headers = new Headers();
this.headers.append('Content-Type', 'x-www-form-urlencoded');
let body = JSON.stringify({name:"Lionel Messi"});
return this.http
.post('http://localhost:8081/save',body
,this.headers);
}
nodejs code
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/save', function (req, res) {
console.log("Got a POST request for the homepage");
console.log(req.body);// output - {}
res.send('Hello POST');
})
Network Section in Chrome....payload is proper
alert method in node.js will not work . You need to use console.log("Hello");
Second thing is to get body data , use req.body.name
My way of writing code is like below and it works
$http({
method: 'POST',
url: 'http://localhost:8081/save',
data: {name:"Lionel Messi"}
})
.success(function(data) {
return data
})
.error(function(error) {
// handle error
});
Other way you can try is:
$http.post('http://localhost:8081/save', {name:"Lionel Messi"})
.then(function(data) {return data})
.catch(function() {console.log("Error Occured");});
You can do it like this-
Suppose you have sent username and password from your browser by post method.
app.post("/ url,function(request,response)
{ var username=request.body.username;
var password=request.body.password;})

Resources