Since yesterday I'm trying to get the books on the google API for an exercise, I had to pass on a lot of errors and here is my final code, from this moment I can't move forward:
export async function fetchGoogle (url, options = {}) {
const headers = {Accept : 'application/json', ...options.headers}
const r = await fetch(url, {...options, headers})
if (r.ok) {
return r.json()
}
throw new Error ('Error server', {cause :r})
}
// Bypass error 200
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
Then I import this into my main script :
import { fetchGoogle } from "./api.js"
const books = await fetchGoogle ('https://www.googleapis.com/auth/books')
console.log(books)
After all these fights I get the error : Uncaught ReferenceError: require is not defined
at api.js:12:15
Thanks in advance for helping
Related
My application uses the Zoom API with OAuth.
The process is well put in the zoom developer docs and I followed them
I created a zoom app in the developer's account and got the clientID and clientSecret.
First we need to get the Authorization code from "https://zoom.us/oauth/authorize". With this code we can get the access token from "https://zoom.us/oauth/token". Pretty straight forward. I tried it on Postman and all the APIs work.
My JS code below doesn't work and keeps failing to do this task.
const express = require('express');
const axios = require('axios');
let token = null;
const app = express();
const clientId = 'ADqR4l7KTfMmXXXXXXXX';
const clientSecret = 'mhVytefIFS4fSqQ3XXXXXXXXXX';
const redirectURL = 'http://localhost:3000/oauth-callback'
app.get('/', (req, res) => {
res.redirect(`https://zoom.us/oauth/authorize?response_type=code&client_id=${clientId}&redirect_uri=${redirectURL}`);
});
app.get('/oauth-callback', (req, res) => {
const body = {
client_id: clientId,
client_secret: clientSecret,
code: req.query.code
};
const opts = { headers: { accept: 'application/json' } };
axios.post(`https://zoom.us/oauth/token`, body, opts).
then(res => res.data['access_token']).
then(_token => {
console.log('My token:', token);
token = _token;
res.json({ ok: 1 });
}).
catch(err => res.status(500).json({ message: err.message }));
});
app.listen(3000);
console.log('App listening on port 3000');
zoom dev acct:
zoom dev account
Error message:
Error message
How can I get the access token? Please help me find my errors in the code.
greeting kings
i have api request that have cors problem. I'm able to solve by using proxy setup using nodejs. Unfortunately im trying to pass certain query parameter from my main js to app.js(nodejs proxy) so my api can have certain value from main js. How to solve this or should point me where should i read more.below is my code
main js
const inputValue = document.querySelector('input').value
//this value is maybeline
app.js(node.js proxy)
const express = require('express')
const request = require('request');
const app = express()
app.use((req,res,next)=>{
res.header('Access-Control-Allow-Origin', '*');
next();
})
app.get('/api', (req, res) => {
request(
{ url: 'https://makeup-api.herokuapp.com/api/v1/products.json?brand=covergirl' },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: err.message });
}
res.json(JSON.parse(body));
}
)
});
const port = process.env.PORT || 5500
app.listen(5500,()=>console.log(`listening ${port}`))
I want to pass inputValue as query to api in app.js
as
https://makeup-api.herokuapp.com/api/v1/products.json?brand=${type}
How to do it or point me any direction?
note:this api work withour cors problem.This is an example api..tq
You can use stringify method from qs module.
const { stringify } = require("qs");
app.get("/api", (req, res) => {
request(
{
url: `https://makeup-api.herokuapp.com/api/v1/products.json?${stringify(
req.params
)}`,
}
/// Rest of the code
);
});
I'm trying to setup CSRF tokens so that I can do a number of checks before issueing a token to the client to use in future requests.
Taking the guidance from the csurf documentation, I've setup my express route with the following:
const express = require('express');
const router = express.Router({mergeParams: true});
const csurf = require('csurf');
const bodyParser = require('body-parser');
const parseForm = bodyParser.urlencoded({ extended: false });
const ErrorClass = require('../classes/ErrorClass');
const csrfMiddleware = csurf({
cookie: true
});
router.get('/getCsrfToken', csrfMiddleware, async (req, res) => {
try {
// code for origin checks removed for example
return res.json({'csrfToken': req.csrfToken()});
} catch (error) {
console.log(error);
return await ErrorClass.handleAsyncError(req, res, error);
}
});
router.post('/', [csrfMiddleware, parseForm], async (req, res) => {
try {
// this returns err.code === 'EBADCSRFTOKEN' when sending in React.js but not Postman
} catch (error) {
console.log(error);
return await ErrorClass.handleAsyncError(req, res, error);
}
});
For context, the React.js code is as follows, makePostRequest 100% sends the _csrf token back to express in req.body._csrf
try {
const { data } = await makePostRequest(
CONTACT,
{
email: values.email_address,
name: values.full_name,
message: values.message,
_csrf: csrfToken,
},
{ websiteId }
);
} catch (error) {
handleError(error);
actions.setSubmitting(false);
}
Postman endpoint seems to be sending the same data, after loading the /getCsrfToken endpoint and I manually update the _csrf token.
Is there something I'm not doing correctly? I think it may be to do with Node.js's cookie system.
I think your problem is likely to be related to CORS (your dev tools will probably have sent a warning?).
Here's the simplest working back-end and front-end I could make, based on the documentation:
In Back-End (NodeJS with Express) Server:
In app.js:
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
const cors = require('cors');
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
var app = express()
const corsOptions = {
origin: "http://localhost:3000",
credentials: true,
}
app.use(cors(corsOptions));
app.use(cookieParser())
app.get('/form', csrfProtection, function (req, res) {
res.json({ csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function (req, res) {
res.send('data is being processed')
})
module.exports = app;
(make sure you update the corsOptions origin property to whatever your localhost is in React.
In Index.js:
const app = require('./app')
app.set('port', 5000);
app.listen(app.get('port'), () => {
console.log('App running on port', app.get('port'));
});
In React:
Create file "TestCsurf.js" and populate with this code:
import React from 'react'
export default function TestCsurf() {
let domainUrl = `http://localhost:5000`
const [csrfTokenState, setCsrfTokenState] = React.useState('')
const [haveWeReceivedPostResponseState, setHaveWeReceivedPostResponseState] = React.useState("Not yet. No data has been processed.")
async function getCallToForm() {
const url = `/form`;
let fetchGetResponse = await fetch(`${domainUrl}${url}`, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"xsrf-token": localStorage.getItem('xsrf-token'),
},
credentials: "include",
mode: 'cors'
})
let parsedResponse = await fetchGetResponse.json();
setCsrfTokenState(parsedResponse.csrfToken)
}
React.useEffect(() => {
getCallToForm()
}, [])
async function testCsurfClicked() {
const url = `/process`
let fetchPostResponse = await fetch(`${domainUrl}${url}`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"xsrf-token": csrfTokenState,
},
credentials: "include",
mode: 'cors',
})
let parsedResponse = await fetchPostResponse.text()
setHaveWeReceivedPostResponseState(parsedResponse)
}
return (
<div>
<button onClick={testCsurfClicked}>Test Csurf Post Call</button>
<p>csrfTokenState is: {csrfTokenState}</p>
<p>Have we succesfully navigates csurf with token?: {JSON.stringify(haveWeReceivedPostResponseState)}</p>
</div>
)
}
Import this into your app.js
import CsurfTutorial from './CsurfTutorial';
function App() {
return (
<CsurfTutorial></CsurfTutorial>
);
}
export default App;
That's the simplest solution I can make based on the CSURF documentations example. It's taken me several days to figure this out. I wish they'd give us a bit more direction!
I made a tutorial video in case it's of any help to anyone: https://youtu.be/N5U7KtxvVto
I'm really struggling with an example project for an online course and I think there's alot I'm doing wrong with the code. The example code I'm given in these example projects frequently don't work and I need to add/change/remove parts all over the place. I think I'm making alot of wrong changes. The first problem I'm having is that I get this error when I go to /addAnimal:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
The second problem I'm having is that when I go to /fakeAnimalData I see the data in the body of the HTML but not in the console as a javascript object. Then when I go to /addAnimal and submit the form I get the fav data in the body of the HTML but not in the console. The ultimate goal is to get the data from /fakeAnimalData AND the data (animal and fact) from the form in /addAnimal to show up in the console as a single javascript object with all three elements (animal, fact, fav). This is the code I have so far:
server.js:
/* Empty JS object to act as endpoint for all routes */
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('project1'));
const port = 8000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
const animalData = [];
const fakeData = {animal: "lion", fact: "a lion's roar can be heard five miles away"};
app.get('/fakeAnimalData', getFakeData);
function getFakeData(req, res) {
res.send(fakeData)
};
app.get('/all', getData);
function getData(req, res){
res.send(animalData)
console.log(animalData)
}
// function sendData (request, response) {
// response.send(projectData);
// };
// POST route
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
}
// POST an animal
const data = [];
// TODO-Call Function
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(addAnimal)
function addAnimal(req, res){
newEntry = {
animal: req.body.animal,
facts: req.body.fact,
fav: req.body.fav
}
data.push(req.body);
res.status(200).send(req.body);
animalData.push(newEntry)
res.send(animalData)
console.log(animalData)
};
app.js:
function performActuion(e){
const fav = document.getElementById('fav').value;
const getAnimal = async (url) =>{
const res = await fetch(url);
try {
const data = await res.json();
console.log(data)
return data;
} catch(error) {
console.log()
}
};
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json();
console.log(newData);
// console.log(newData);
return newData.json()
console.log(await response.json());
return await response.json()
}catch(error) {
console.log("error", error);
// appropriately handle the error
};
};
// TODO-Call Function
getAnimal('/fakeAnimalData')
.then(async function(data){
console.log(data)
let res = await postData('/addAnimal', (animal: data.animal, fact: "lions are fun", fav: fav));;
console.log(res);
})();
Any guidence at all would be much, much appreciated.
Thanks,
Mike
function addAnimal(req, res){
newEntry = {
animal: req.body.animal,
facts: req.body.fact,
fav: req.body.fav
}
data.push(req.body);
// >>>>res.status(200).send(req.body);
animalData.push(newEntry)
res.send(animalData)
console.log(animalData)
};
You can't modify the res object after it has been already been sent, thus the error
Following the example from OAuth2WebServer from google I'm trying to set up an authentication flow from an express app using the HTTP/REST method they have but with every request I am returned with an error
I went through Google OAuth “invalid_grant” nightmare — and how to fix it but unfortunately it did not help.
{
error: "unsupported_grant_type",
error_description: "Invalid grant_type: "
}
This is a shortened version of the error I am receiving. If you need to see more of the error let me know and I can post it.
Server
const express = require('express');
const axios = require('axios');
const { web } = require('./src/client_id.json');
const app = express();
const { client_id, client_secret } = web;
let count = 0;
app.use(express.json());
/*************************
** REDIRECT USER TO GOOGLE AUTH **
*************************/
app.get('/', (req, res) => {
const redirect_uri = 'http://localhost:5000/auth';
const scope = 'https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly';
const access_type = 'offline';
res.redirect(`https://accounts.google.com/o/oauth2/v2/auth?scope=${ scope }&access_type=${ access_type }&redirect_uri=${ redirect_uri }&response_type=code&client_id=${ client_id }`);
});
/*************************
** ON AUTH WE EXCHANGE ACCESS TOKEN FOR REFRESH TOKEN **
*************************/
app.get('/auth', (req, res) => {
count++;
if (count >= 2) {
return res.redirect('http://localhost:3000');
}
const { code } = req.query;
const redirect_uri = 'http://localhost:5000/auth';
const grant_type = 'authorization_code';
axios.post('https://www.googleapis.com/oauth2/v4/token', {
code,
client_id,
client_secret,
redirect_uri,
grant_type
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(data => {
console.log(data)
res.redirect('http://localhost:3000');
})
// ALWAYS HITS THE CATCH "Invalid grant_type"
.catch(err => {
console.log(err);
console.log('ERROR')
});
});
app.listen(5000, console.log('Server listening on port 5000'));