Hapi send request to current local server - hapi.js

I have a graphql running on my server. And I have an upload route like this:
server.route({
config: {
cors: {
origin: ['*'],
credentials: true
},
payload: {
output: 'stream',
parse: true,
maxBytes: 50869457,
allow: 'multipart/form-data'
},
},
method: ['POST', 'PUT'],
path: '/uploadAvatar',
handler: (request, reply) => {
const data = request.payload;
data.identity = options.safeGuard.authenticate(request);
// REQUEST TO THE SAME SERVER THIS IS RUNNING ON
}
});
I want to send a request to the same server as I am in if that makes sense.. How to do that?
btw I want to call localhost:3004/graphql if it's running on localhost:3004 but on production it's running on port 80.

You can use hapi's built in server.inject method for handling internal routing, the docs for inject are here

Related

Backend api call not working in Vue(front)

My environment
front - windows, port 3000
backend - linux (ubuntu) in docker container, port 5000
Vue(front) tsconfig.json
export default defineConfig({
plugins: [vue(), vueJsx()],
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url)),
},
},
server: {
host: true,
port: 3000,
proxy: {
"/api": {
target: "http://127.0.0.1:5000",
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});
front api call code
const response = await axios.post("http://127.0.0.1:5000/users/login?email=" + code);
backend(Nestjs) - main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: 'http://localhost:3000',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
});
await app.listen(5000);
}
bootstrap();
I expect the api call to go to the backend, localhost:5000
but i get a 404 error
When I tried with postman, I got normal return, but when I sent the request using axios in Vue with the same request, I got 404 not found.
The most incomprehensible thing is that with the current settings, it was normally requested when developing in the past.
I don't know how to fix this
please help a lot
Repositories currently being edited: https://github.com/PracticeofEno/ft_transcendence
thanks
omg... I send POST message..
But api is GET Message

API Requests that need Authorization return CORS error

Initial Problem
I work on a web application (react) that accesses data via an API. The API runs for development reasons on a docker container on my local machine. Simple GET requests (via axios) got me CORS complications (...has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.).
A bit of researching solved my problem by running a nginx reverse proxy in another container. I basically used this configuration for the nginx server.
New Problem
As I progress in building my application, I come to a point where I need to send the JWT to the API to access and alter some entries. Requests that need sending a JWT again get me CORS error messages.
The API checks the JWT signature (RS256 generated). I just have to forward it to the API server.
ALSO: simple curl requests with the JWT from the console are working.
Configuration
axios
const axiosConfig = {
responseType: "json",
withCredentials: false,
mode: "no-cors",
headers: {
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
'Content-Type': 'application/json',
'Authorization': 'Bearer <JWT as string>',
},
};
const apiGetRequest = async (route, callback) => {
try {
const apiUrl = URL + route;
axios.get(apiUrl, {
axiosConfig
})
.then(res => {
callback(res);
})
.catch(function (error) {
console.log(error);
});
} catch (error) {
console.log(error);
}
}
nginx configuration
Docker Image for api
version: "3.9"
services:
db:
image: mariadb:latest
container_name: db
env_file:
- ./mariadb/.env
volumes:
- ./mariadb/create-schema-docker.sh /docker-entrypoint-initdb.d
- db-data:/var/lib/mysql
ports:
- 3306:3306
rest:
image: mds4ul/station-registry:latest
container_name: api
environment:
- DB_HOST=db
- CONTEXT_PATH=api
env_file:
- ./rest/.env
depends_on:
- db
ports:
- 80:8080
volumes:
db-data:
Questions
Why do I get CORS errors for requests where a jwt is needed and not for requests that do not require one?
Which part do I have to change to make this work?
So answer another question to an embarrassing easy problem of mine.
I switched to an express.js proxy server with the following configuration:
const express = require('express')
const app = express()
const axios = require('axios')
const cors = require('cors')
var bodyParser = require('body-parser')
app.use(cors({
origin: '*'
}))
app.use(bodyParser.json())
require('dotenv').config()
const headers = {
"X-Authorization": <token>,
}
app.get(':endpoint([\\/\\w\\.-]*)', function (req, res) {
const endpoint = (process.env.API_BASE_URL).replace(/\/$/, "") + req.params.endpoint;
axios.get(endpoint, { headers }).then(response => {
res.json(response.data)
}).catch(error => {
res.json(error)
})
})
app.listen(3001)
I assume I just could not figure out my nginx configuration for this use case. So with express.js I can access now resources which need authorization.

createProxyMiddleware not working on Azure Webapp

I'm running an Angular Universal application that is talking to an API. Now I'm trying to set up a proxy in the Universal server that proxies API requests to the actual API server:
server.use(['/api', '/sitemap.txt'], createProxyMiddleware({
target: process.env.API_URL,
onProxyReq: req => {
console.log('Using origin: ' + getOrigin(req.getHeaders()));
req.setHeader('origin', getOrigin(req.getHeaders()));
},
pathRewrite: {'^/api': ''}
}));
This works perfectly when running locally, but when running it on the server (Azure WebApp), it doesn't work. I can see the console log being called in the WebApp logs, but the resulting document is the Angular application with a message "page not found".
I'm totally out of ideas on where to look for solutions.
Edit:
I tried another proxy middleware and it does do the trick. This code works both locally and on Azure.
import * as proxy from 'express-http-proxy';
// ...
server.use(['/api', '/sitemap.txt'], proxy(process.env.API_URL, {
proxyPathResolver: req => {
let url: string = req.url;
if (url.startsWith('/api')) {
url = url.substr(4);
}
return url;
},
proxyReqOptDecorator(proxyReqOpts, srcReq) {
proxyReqOpts.headers['origin'] = getOrigin(proxyReqOpts.headers);
return proxyReqOpts;
}
}));
But it has some other limitations that make it unusable for our project, so I still need this resolved.
I have it working correctly now. This is the current setup:
server.use(
'/api',
createProxyMiddleware({
target: process.env.API_URL,
changeOrigin: true,
headers: {
Connection: 'keep-alive',
},
onProxyReq: (proxyReq, req, _res) => {
proxyReq.setHeader('origin', getOrigin(req.headers));
},
pathRewrite: {
'^/api': '',
},
})
);
So I added changeOrigin and the keep-alive header. I'm not sure which of the two resolved the issue, once I got it to work I never bothered to check it out. I suspect it's the header, though.

Proxy not hitting in Nuxt Axios causing CORS

I am receiving following CORS error
Access to XMLHttpRequest at 'https://gw.bilinfo.net/listingapi/api/export' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My Nuxt.config.js looks like this:
proxy: {
'/listingapi/api/export/': {
target: 'https://gw.bilinfo.net/',
pathRewrite: { '^/listingapi/api/export/': '' },
changeOrigin: true
}
},
axios: {
proxy: true,
baseURL: 'http://localhost:3000', // Used as fallback if no runtime config is provided
withCredentials: true,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
},
My data fetching component looks like this:
async fetch() {
const data = await this.$axios.$get(
'https://gw.bilinfo.net/listingapi/api/export',
{
credentials: true,
auth: {
username: 'XXXXXXX',
password: 'XXXXXXX'
}
}
)
this.biler = data.Vehicles
},
Everything works fine on refresh, but clicking around the website, gives a CORS error an data disappears. Somehow I am not hitting the proxy, but I can't understand why.
while proxying you have to call it below way
async fetch() {
const data = await this.$axios.$get(
'/listingapi/api/export',
{
credentials: true,
auth: {
username: 'XXXXXXX',
password: 'XXXXXXX'
}
}
)
this.biler = data.Vehicles
}
Below proxy pass code means whenever you want to hit https://gw.bilinfo.net/Example API URL than you have to call it /listingapi/api/export/Example
proxy: {
'/listingapi/api/export/': {
target: 'https://gw.bilinfo.net/',
pathRewrite: { '^/listingapi/api/export/': '' },
changeOrigin: true
}
},
Basically, what you add as pathRewrite will be replaced with the target URL.
Hope this will help!!

Getting ERR_CERT_AUTHORITY_INVALID with axios

I'm trying to do a post request via https with vue-axios.
However, since i'm using a self-signed certificate that i created, i'm getting the following error:
net::ERR_CERT_AUTHORITY_INVALID
Upon searching i found that most people solve this by doing the following
const instance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
});
instance.get('https://something.com/foo');
// At request level
const agent = new https.Agent({
rejectUnauthorized: false
});
axios.get('https://something.com/foo', { httpsAgent: agent });
I tried both option but didn't have any success with them.
I used the npm https module for the https.Agent.
Does anyone know how to solve this problem? or should I just change from axios to other modules?
edited:
the piece of code I'm running with the error at the moment:
const axiosInstance = axios.create({
baseURL: 'https://localhost:5000',
httpsAgent: new https.Agent({
rejectUnauthorized: false
}),
});
axiosInstance.post('/user', LoginRequest,
{ headers: { 'Content-Type': 'application/json' } })
.then(response => this.assignLogin(response.data));
tried to change to a module named needle and use https but had the same error:
needle:
const headers = { 'Content-Type': 'application/json' };
const options = {
method: 'POST',
headers: headers,
rejectUnauthorized: false,
requestCert: true,
agent: false,
strictSSL: false,
}
needle.post('https://localhost:5000/user', LoginRequest, options).on('end', function() { })
https:
const options = {
hostname: 'localhost',
port: 5000,
path: '/user',
strictSSL: false,
rejectUnauthorized: false,
secureProtocol: 'TLSv1_method',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
this.assignLogin(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(LoginRequest);
req.end();
Since you mention that you are "using a self-signed certificate that you created", I guess that you are using this for local development tests. I had a similar issue, when testing locally in Chrome.
As this error message (net::ERR_CERT_AUTHORITY_INVALID) is a way of Chrome blocking a URL with an "unsafe" certificate, you need to solve this issue through Chrome, telling it that you trust the certificate.
The solution I use is the old one thisisunsafe. (ONLY USE THIS SOLUTION IF YOU REALLY TRUST THE CERTIFICATE, I.E., IT'S YOUR OWN CERTIFICATE):
SOLUTION: Just open a tab in Chrome, try to open a URL with your server address (in your case, https://localhost:5000/). Chrome will display a warning message, so you click anywhere in the window, and type thisisunsafe. Chrome will now allow access to this certificate. When you reload the client again and try to request the server, it will work.