I'm trying to make get request via token from local storage but it is giving me Request aborted error.
Here is My nodeJS code :
//Read
app.get('/:username',verify, (req, res) => {
console.log('Welcome to roffys server')
Todo.find({'username' : req.params.username})
.exec((err, todo) => {
if (err) {
console.log('Error retrieving todos')
} else {
res.json(todo)
}
})
})
Here is the Verify function :
const jwt = require('jsonwebtoken')
module.exports = function (req,res,next){
const token = req.header('Authentication')
if(!token) return res.status(401).send('Access Denied')
try {
const verified = jwt.verify(token, 'secretkey')
req.user = verified
}catch (err) {
res.status(400).send(
'Invalid token'
)
next()
}
And here is my FE on ReactJS component:
componentDidMount() {
axios
.get(`http://localhost:8080/${localStorage.getItem('username')}`,{
headers : {
Authentication : localStorage.getItem('token')
}
})
.then((res) => {
this.setState({todos: res.data})
this.setPageCount()
})
.catch((err) => {
console.log("err", err);
});
}
None of yow methods return anything.
componentDidMout () {
return axios.get(url, config)
.then (res=> this.setState(myProp: res.data});
......
Back
var verify = require(“./path/to verify”);
//Read
app.get('/:username',verify, (req, res) => {
return Todo.find({'username' : req.params.username})
.exec()
.then(todo=> res.json(todo))
.catch(console.log);
})
Related
I got this strange error I don't understand
Have been using for a long time and it worked, just yesterday it stopped working
module.exports.login = async(req, res, next) => {
const { username, password } = req.body;
const ips = req.user.ip;
const email = req.user.email;
fetch('https://api.ipify.org')
.then((res) => res.text())
.then(ip => {
fetch(`http://ip-api.com/json/${ip}`)
.then(response =>response.json())
.then(data => {
console.log(data)
const city = data.city
const country = data.country
const location = `${city}, ${country}`
if (ip === ips) {
req.flash('success', `welcome back ${username}`);
const redirectUrl = req.session.returnTo || '/index';
console.log(req.session.returnTo)
delete req.session.returnTo;
res.redirect(redirectUrl);
} else {
...
};
})
.catch(err => {
req.logout(function(err) {
if (err) { return next(err); }
req.flash('error', 'An error occured')
res.redirect('/login');
});
})
})
.catch(err => {
req.logout(function(err) {
if (err) { return next(err); }
req.flash('error', 'An error occured, This may be due to bad network')
res.redirect('/login');
});
})
};
The last catch(err with message 'An error occured, This may be due to bad network' is what am getting
But it working in m localhost, but when I upload it online it does not take any action rather it trows error
Please any help with this?
Thanks for any future help
Trying to get user ip with fecth('api.ipify.org') but is giving me error when I put it online but working in my localhost
I actually found the answer, node-fetch just currently updated their v3.0.3 package
Reasons is that it works only in ESM which you use 'import' instead of require(), And if that does not work you get error except you go back using v2 or less.
Which is not Ok for me so I diverted to use 'axios'
npm install axios
Example
async() {
await axios.get('api.ipify.org')
.then(response => {
console.log(response)
}.catch(err => console.log(err))
return
};
The response contains the ip address
But if you still need to use node-fetch use the link 'node-fetch'
Full code below
module.exports.login = async(req, res, next) => {
const { username, password } = req.body;
const ips = req.user.ip;
const email = req.user.email;
await axios.get('https://api.ipify.org')
.then(async(response) => {
const ip = response.data
await axios.get(`http://ip-api.com/json/${ip}`)
.then(response => {
const data = response.data
console.log(data)
const city = data.city
const country = data.country
const location = `${city}, ${country}`
if (ip === ips) {
req.flash('success', `welcome back ${username}`);
const redirectUrl = req.session.returnTo || '/index';
console.log(req.session.returnTo)
delete req.session.returnTo;
res.redirect(redirectUrl);
} else {
...
};
})
.catch(err => {
req.logout(function(err) {
if (err) { return next(err); }
req.flash('error', 'An error occured')
res.redirect('/login');
});
})
})
.catch(err => {
req.logout(function(err) {
if (err) { return next(err); }
req.flash('error', 'An error occured, This may be due to bad network')
res.redirect('/login');
});
})
};
I am trying to pass data using axios.post method to the express server backend but it gives undefined.
Here's the frontend code:
const login = async (codeParam) => {
if (codeParam.code.length > 1) {
try {
console.log("login with", codeParam) //returns the right value {code: 'value'}
const response = await axios.post(
"http://localhost:8000/getAccessToken",
codeParam
)
if (response.data) {
console.log("access token:", response.data.access_token)
localStorage.setItem("user", JSON.stringify(response.data.access_token))
localStorage.setItem("isLoggedIn", true)
}
} catch (error) {
console.log(error)
}
}
}
And here's the backend route:
app.post("/getAccessToken", (req, res) => {
console.log("code", req.query.code) //returns undefined
axios
.post("https://github.com/login/oauth/access_token", {
client_id: process.env.REACT_APP_CLIENT_ID,
client_secret: process.env.REACT_APP_CLIENT_SECRET,
code: req.query.code,
redirect_uri: process.env.REACT_APP_REDIRECT_URI,
})
.then((result) => {
console.log("access token backend", result.data)
})
.catch((err) => {
console.log("error:", err)
})
})
I am trying to pass the "codeParam" object to the backend route but it's giving undefined. Here's what I get on the console:
code undefined
access token backend error=bad_verification_code&error_description=The+code+passed+is+incorrect+or+expired.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-oauth-app-access-token-request-errors%2F%23bad-verification-code
The problem is:
req.query.code
It should return something or maybe I am doing it wrong?
I am trying to make a get route for this API:
https://api.nasa.gov/mars-photos/api/v1/rovers/opportunity/photos?sol=1000&api_key=92Ll6nGuQhfGjZnT2gxaUgiBhlCJ9K1zi2Fv5ONn
And although the syntax for the get route, the API still doesn't work in postman nor in client-side.
Here's the get route code:
app.get('/roverInfo/:rover_name', async (req, res) => {
const { rover_name } = req.params
try {
let images = await fetch(`https://api.nasa.gov/mars-photos/api/v1/rovers/${rover_name}/photos?sol=1000&api_key=${process.env.API_KEY}`).then((res) => res.json())
res.send({ images })
} catch (err) {
console.log('error:', err)
}
})
sandbox here
and here's the client-side request:
const showRovers = async (rovers) => {
try {
await fetch(`https://localhost:3000/roverInfo/:rover_name`)
.then((res) => {
return res.json()
})
.then((rovers) => updateStore(store, { rovers }), console.log(rovers))
} catch (error) {
console.log('errors:', error)
}
}
and here's the error I am getting:
Failed to load resource: net::ERR_SSL_PROTOCOL_ERROR
ADVISE: Don't mix await/async with .then, use either one
app.get("/roverInfo/:rover_name", async (req, res) => {
const { rover_name } = req.params;
try {
const res = await fetch(
`https://api.nasa.gov/mars-photos/api/v1/rovers/${rover_name}/photos?sol=1000&api_key=${process.env.API_KEY}`
) // removed .then
const images = await res.json(); // await response to json
res.send({ images });
} catch (err) {
console.log("error:", err);
}
});
02. should be http instead of https
03. need to pass rover name to param instead of using :rover_name
let getRovers = showRovers('opportunity');
const showRovers = async (roverName) => {
try {
console.log("roverName", roverName)
// use http here
await fetch(`http://localhost:3000/roverInfo/${roverName}`)
.then((res) => {
return res.json();
})
.then((rovers) => updateStore(store, { rovers }));
} catch (error) {
console.log("errors:", error);
}
};
I have an issue querying in my firebase database. I am trying to get all data of an authenticated user from my endpoint ".../api/user".
This is the route in my code:
// GET DATA OF USER
router.route("/user").get(FBAuth, getAuthenticatedUser);
Here I use a middleware which decodes the token and sets it in the req.user, and of course verifies if the user is authenticated:
// FBAuth middleware
module.exports = (req, res, next) => {
admin
.auth()
.verifyIdToken(idToken)
.then((decodedToken) => {
req.user = decodedToken;
return db
.collectionGroup("users")
.where("idUser", "==", req.user.uid)
.limit(1)
.get();
})
.then((data) => {
req.user.name = data.docs[0].data().name
return next();
})
.catch((err) => {
console.error("Error while verifying token", err);
return res.status(403).json(err);
});
};
All the above works fine, but after the req.user set successfully, we go to the function "getAuthenticatedUser" which doesn't work:
//Controller
exports.getAuthenticatedUser = (req, res) => {
let userData = {};
db.collectionGroup("users")
.where("email", "==", req.user.email) //".where("idUser", "==", req.user.uid)" nothing works here
.limit(1)
.get()
.then((doc) => {
if (doc.exists) { // Always goes to the else no matter what query I do
userData.credentials = doc.data();
return db
.collection("comptes")
.doc(req.user.name)
.collection("courses")
.get();
}else{
return res.status(400).json({email: 'Email not found => ' + req.user.email});
// the req.user.email does exist and contain the right email, and also exists in the database...
}
})
.then((data) => {
if (data.exists) {
userData.courses= [];
data.forEach((doc) => {
userData.courses.push(doc.data());
});
}
return res.json(userData);
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
};
I don't see how the query can work for the logging, for the middleware but not for the actual controller which must use this setup before cause it is a private route?
I finally fixed it, if anyone has the same issue here is the solution:
exports.getAuthenticatedUser = (req, res) => {
let userData = {};
db.collectionGroup("users")
.where("email", "==", req.user.email)
.limit(1)
.get()
.then((doc) => {
if (doc.docs[0].exists) { // <----- doc.docs contain a list of data
userData.credentials = doc.docs[0].data();
return db
.collection("comptes")
.doc(req.user.name)
.collection("courses")
.get();
}
})
.then((data) => {
if (data.exists) {
userData.courses= [];
data.forEach((doc) => {
userData.courses.push(doc.data());
});
}
return res.json(userData);
})
.catch((err) => {
console.error(err);
return res.status(500).json({ error: err.code });
});
};
I am currently experimenting Google Firebase functions to access Google APIs. It's running fine, but I am a little bit lost in trying to manage the errors that could be detected ...
In the .HTTPS getGoogleUsers functions , I would like to return an HTTP status code ( 200 or error code ) , and the data ( or error message )
As far as I can see , I can get errors:
from the connect() function ( 500: Internal server error or 401 Unauthorized )
from the listUsers() function ( 500: Internal server error or 400 Bad Request )
Am I totally or partially wrong ? what should be my strategy in this case ?
thanks for feedback ..
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const {google} = require('googleapis');
const KEY = require('./service-key.json');
// Create JSON Web Token Client
function connect () {
return new Promise((resolve, reject) => {
const jwtClient = new google.auth.JWT(
KEY.client_email,
null,
KEY.private_key,
['https://www.googleapis.com/auth/admin.directory.user'],
'adminuser#mydomain.com'
);
jwtClient.authorize((err) => {
if(err) {
reject(err);
} else {
resolve(jwtClient);
}
});
});
}
function listUsers (client) {
return new Promise((resolve, reject) => {
google.admin('directory_v1').users.list({
auth: client,
domain: 'mydomain.com',
}, (err, response) => {
if (err) {
reject(err);
}
resolve(response.data.users);
});
});
}
function getAllUsers () {
connect()
.then(client => {
return listUsers(client);
})
.catch(error => {
return error;
})
}
exports.getGoogleUsers = functions.https.onRequest((req, res) => {
const users = getAllUsers();
if (error) {
status = error.status;
data = error.message;
} else {
status = 200;
data = users;
}
res.send({ status: status, datas: data })
});
I think you are looking for
function getAllUsers () {
return connect().then(listUsers);
//^^^^^^
}
exports.getGoogleUsers = functions.https.onRequest((req, res) => {
getAllUsers().then(users => {
return {status: 200, datas: users};
}, error => {
return {status: error.status, datas: error.message};
}).then(response => {
res.send(response);
});
});
This uses the .then(…, …) method with two callbacks to distinguish between success and error case, and to wait for the result of the promise.