I cannot get my api to work with my express server with OAuth2 logic, I always get an error since I had
res.render i commented it out now the whole part is router.get does not work for axios.post inside it. Here is the code snippet:
mport {Request, Response, Router} from 'express';
import {writeFile, readFile, unlinkSync, unlink} from 'fs';
import {URLSearchParams} from 'url';
import axios from 'axios';
import qs from 'querystring';
const router: Router = Router();
...
//OIDC Callback
router.get('/callback', async function ({ query }, res, next) {
console.log("In Callback...");
if (query.error) {
const description = query.error_description;
return res.render('error', {
error: description
});
}
try {
const code = query.code;
const basicAuthHeader = Buffer.from(`${settings.clientId}:${settings.clientSecret}`).toString('base64');
console.log("Inside callback...token details: "+ settings.clientSecret);
const main_token = (await axios.post(metaData.token_endpoint, qs.stringify({
grant_type: 'authorization_code',
redirect_uri: settings.callbackUrl,
code,
scope: settings.scopes
}), {
headers: {
'Accept': 'application/json',
'Authorization': `Basic ${basicAuthHeader}`,
'Content-Type': 'application/x-www-form-urlencoded'
}
})).data;
const checkAURL = await needsAURL();
if (checkAURL) {
res.redirect(checkAURL);
} else {
// res.render('index', settings);
console.log("inside else...");
}
} catch (e) {
console.log("Error..Need organization access");
// return res.render('error', {
// error: e
// });
}
});
I am pretty sure it is because of express router settings but I cannot fix this. If i make a axios.get inside router.get it works. But in this case I cannot do that.
Did I use express router correctly? Because I have never used it before.
Related
Can someone tell me what mistake I am making or tell me how to set the header in axios patch request. when I am running the API through postman, everything is working fine but when I connect it with the front end, an error comes up saying that the JWT is not provided on the backend
here is the frond end code :
import React, { useEffect } from 'react';
import { useParams } from 'react-router';
import axios from 'axios';
const Loader = () => {
const parmas = useParams();
const { id } = parmas;
console.log(id);
useEffect(() => {
const fetchBags = async () => {
try {
const res = await axios.patch('http://localhost:4001/public/verify', {
headers: {
'Content-Type': 'application/json',
Token: id,
},
});
console.log(res);
console.log('CBM', { res });
} catch (error) {
console.log(error);
}
};
fetchBags();
}, []);
return <div>this is loader</div>;
};
export default Loader;
below is my backend code:
export const verifyUser = async (data) => {
const token1 = data.header("Token");
try {
const verified = jwt.verify(token1, getTokenSecret());
console.log(verified)
await userModel.verifyUser(verified);
return {
message: "success",
};
} catch (error) {
console.log(`Auth Service > verifyUser > ${error.toString()}`);
throw error;
}
};
this error is comming:
Error
From docs
axios.patch(url[, data[, config]])
As you can see you pass config in 3rd argument not 2nd.
const res = await axios.patch(
'http://localhost:4001/public/verify',
{}, // data (2nd argument)
{
headers: {
'Content-Type': 'application/json',
Token: id,
},
} // config (3rd argument)
)
Im building a application using express and I dont want to use a bundler. When I import the axios module it gives me the next error: "Uncaught TypeError: Failed to resolve module specifier "axios". Relative references must start with either "/", "./", or "../"."
I also made a repository of the entire project so far here: https://github.com/klaus4323/Natours-Nodejs.git
The code where I want to use axios is in the login.js (I am doing the nodejs online class of Jonas Schemetmann) file:
import axios from 'axios';
import { showAlert } from './alerts.js';
export const login = async (email, password) => {
try {
const res = await axios({
method: 'POST',
url: 'http://127.0.0.1:3000/api/v1/users/login',
data: { email, password },
});
if (res.data.status === 'success') {
showAlert('success', 'Logged in succesfully');
window.setTimeout(() => {
location.assign('/');
5000);
}
catch (err) {
showAlert('error', err.response.data.message);
}
};
export const logout = async () => {
try {
const res = await axios({
method: 'GET',
url: 'http://127.0.0.1:3000/api/v1/users/logout',
});
if ((res.data.status = 'success')) location.reload(true);
catch (err) {
showAlert('error', 'Error logging out. Try Again!');
}
};
Use like this
import * as axios from 'axios'
Cannot send form data as 'Multipart/formdata' Content type in react-native expo app.
when we send formData object in post request in react -native app, we cant get req.body of req.files from node backend
export const saveUserAddVisitor = async data => {
try {
const apiUrl = configConstants.apiUrlWithPort;
const addVisitorData = await axios.post(
`${apiUrl}/api/v1/mobile/apartment/member`,
data,
{
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
},
);
return addVisitorData;
} catch (err) {
return err;
}
};
You can try something like this which works without Axios:
export const saveUserAddVisitor = async data => {
var data = new FormData()
data.append('foo', {
...
})
try {
const apiUrl = configConstants.apiUrlWithPort;
const addVisitorData = await fetch(`${apiUrl}/api/v1/mobile/apartment/member`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
},
body: data
})
return addVisitorData;
} catch {
return err;
}
}
After I gave you an example of working code for the client, but the problem may be from the server ;)
Your code with axios look like fine, just be sure to send FormData type, like RĂ©mi said here https://stackoverflow.com/a/72454168/16205278
You can construct your FormData before this function and use it directly in your current code with your axios function.
Service :
import axios from "axios";
import configConstants from "./config.js";
/**
* Current function to save User Add Visitor
* #param {*} data
*/
export const saveUserAddVisitor = async (data) => {
try {
const apiUrl = configConstants.apiUrlWithPort;
const addVisitorData = await axios.post(
`${apiUrl}/api/v1/mobile/apartment/member`,
data,
{
headers: {
Accept: 'application/json',
"Content-Type": "multipart/form-data"
}
}
);
return addVisitorData;
} catch (err) {
return err;
}
};
Use :
import {saveUserAddVisitor} from "./index"
const form = new FormData();
form.append("visitor", { firstName: "Jack", lastName: "Doe" });
saveUserAddVisitor(form);
API Express :
Apparently, express can't resolve multipart-form data unless some help, according following ressource : https://codex.so/handling-any-post-data-in-express
You have to use multer middleware :
const multer = require('multer');
app.post('/', multer().none(), function (req, res, next) {
req.body;
//... some code
});
I'm using a middleware to verify token with this code:
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
class VerifyToken {
public verify(req: Request, res: Response, next: NextFunction) {
try {
const authHeader = req.headers["authorization"];
const token = authHeader?.split(" ")[1];
const signature = process.env.JWT_SIGNATURE;
jwt.verify(token, signature);
next();
} catch (error) {
return res.status(401).json("Acess denied");
}
}
}
export default new VerifyToken().verify;
I'm using Jest to test this middleware, here's the code:
import dotenv from "dotenv";
import { NextFunction, Request, Response } from "express";
import verifyToken from "../../src/middlewares/verifyToken";
describe("Verify token", () => {
let mockRequest: Partial<Request>;
let mockResponse: Partial<Response>;
let nextFunction: NextFunction = jest.fn();
beforeAll(() => {
dotenv.config({ path: ".env" });
});
beforeEach(() => {
mockRequest = {};
mockResponse = {
json: jest.fn(),
};
});
it("should verify token with a invalid token", () => {
const token = process.env.TEST_FALSE_TOKEN;
mockRequest = {
headers: {
authorization: `bearer ${token}`,
},
};
verifyToken(mockRequest as Request, mockResponse as Response, nextFunction);
expect(mockResponse.status).toBe(401);
});
it("should verify token with a valid token", () => {
const token = process.env.TEST_TOKEN;
mockRequest = {
headers: {
authorization: `bearer ${token}`,
},
};
verifyToken(mockRequest as Request, mockResponse as Response, nextFunction);
expect(nextFunction).toBeCalledTimes(1);
});
});
When I run a test using Jest, it shows the following error:
TypeError: res.status is not a function
I've already tried to use ErrorRequestHandler with the request but I get the same error.
How can I fix this? Thanks for the help.
Your mocked response doesn't have a status function on it..
mockResponse = {
json: jest.fn(),
status: jest.fn().mockReturnThis(),
};
So I am creating a full stack React app with Express and Node. I have implemented auth0 for authentication and authorization but I am getting the following error, does anyone have any suggestions on how to solve it? Thanks!
"Failed to load resource: the server responded with a status of 431 (Request Header Fields Too Large)"
The following is the class component where I am calling my api/tasks route and passing in the jwt access token from Auth0.
import React, { Component } from 'react';
import axios from "axios";
import {withAuth0} from "#auth0/auth0-react";
import config from "../auth_config.json";
const {apiOrigin = "http://localhost:3001"} = config
componentDidMount() {
const getProtectedTasks = async () => {
const {getAccessTokenSilently} = this.props.auth0;
const accessToken = await getAccessTokenSilently();
try {
const token = accessToken;
const self = this;
const response = await axios.get(`${apiOrigin}/api/tasks`, {
headers: {
Authorization: `Bearer ${token}`
}
})
self.setState({
allTasks: response.data
})
} catch {
}
}
getProtectedTasks()
}
The following is my code that handles the get api/tasks endpoint
const db = require("../models");
const jwt = require("express-jwt");
const jwksRsa = require("jwks-rsa");
module.exports = function (router) {
const authorizeAccessToken = jwt({
secret: jwksRsa.expressJwtSecret({
cache:true,
rateLimit:true,
jwksRequestsPerMinute:5,
jwksUri: `https://task-motivator.us.auth0.com/.well-known/jwks.json`
}),
audience: "https://quickstarts/api",
issuer: "https://task-motivator.us.auth0.com",
algorithms: ["RS256"]
});
router.get("/api/tasks", authorizeAccessToken, (req, res) => {
db.Task.findAll({}).then(data => {
res.json(data);
});
});