is there an easy way to disable SSL validation in Axios. I tried this process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; but it doesn't work.
Here's an example of my code"
const postPosts = () => {
axios
.post("https://xxx.dev.lab", {
Username: "xxx",
Password: "xxx"
})
.then(response => {
console.log(response);
})
.catch(error => {
console.error(error);
});
};
postPosts();
Axios doesn't address that situation so far - you can try:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
BUT THATS A VERY BAD IDEA since it disables SSL across the whole node server..
or you can configure axios to use a custom agent and set rejectUnauthorized to false for that agent as mentioned here
example:
// At instance level
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 });
[ IF YOU RUNNING YOUR APP IN THE DOCKER ]
I solved that issue in my project with 2 steps:
1. Change Docker SSL settings
I edited /etc/ssl/openssl.cnf inside the container
Replace strings:
TLSv1.2 => TLSv1
SECLEVEL=2 => SECLEVEL=1
2. Set min TLS version for your request
import * as https from 'https';
const agent = new https.Agent({
rejectUnauthorized: false,
minVersion: 'TLSv1',
});
axios.post(
"https://xxx.dev.lab",
{ Username: "xxx", Password: "xxx" },
{ httpsAgent: agent }
)
Related
I am trying to pass res from my context into a resolver so that I can call context.res.cookie in my signin function and then send an http only cookie. I have the following code which I am not seeing the cookie added on the client but the sign in function is working besides that:
const resolvers = {
Mutation: {
signin: async (_, { email, password }, context) => {
const user = await User.findOne({ email: email });
if (!user) {
throw new Error("No such user found");
}
const valid = bcrypt.compare(password, user.password);
if (!valid) {
throw new Error("Invalid password");
}
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET,
{
expiresIn: "30m",
});
context.res.cookie("token", token, {
httpOnly: true,
secure: true,
maxAge: 8600,
});
return {
token,
user,
};
},
},
};
I have shortened the above code but originally I am returning the JWT token and mongodb user, I am trying to also add the http cookie of the same token (it will be a different token later when I sepearte access and refresh token).
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req, res }) => {
/* Authentication boiler plate */
return { isAuthenticated, res };
},
});
The above code is just how I am passing the res, not sure if its needed but just in case.
The following is how the function will be called from the front end:
export const Login = () => {
const SIGN_IN = gql`
mutation Signin($email: String!, $password: String!) {
signin(email: $email, password: $password) {
token
user {
id
name
email
}
}
}
`;
const [signIn, { error, loading, data }] = useMutation(SIGN_IN);
const signInFunction = async () => {
signIn({
variables: {
email: email,
password: password,
},
});
};
if (data) {
return <Navigate to="/" />
}
};
So I needed to slightly change both my client and my server to solve my issue. On the client in apollo-client I needed to change my apolloClient from this:
const apolloClient = new ApolloClient({
uri: "http://localhost:3001/graphql",
cache: new InMemoryCache(),
});
to this:
const apolloClient = new ApolloClient({
uri: "http://localhost:3001/graphql",
cache: new InMemoryCache(),
credentials: "include",
});
Now on the server I needed to add cors like this:
const server = new ApolloServer({
typeDefs,
resolvers,
cors: {
origin: "http://localhost:3000",
credentials: true,
},
context: async ({ req, res }) => {
/* insert any boilerplate context code here */
return { isAuthenticated, res };
},
});
Thus passing res to the resolver this way works perfectly fine. However when I was getting the cookie from server now it would get deleted if I refreshed the page thus I needed an explicit expiration date, thus I changed my cookie from:
context.res.cookie("token", token, {
httpOnly: true,
secure: true,
maxAge: 8600,
});
to (24 hour expiration):
context.res.cookie("token", token, {
httpOnly: true,
secure: true,
expires: new Date(Date.now() + 24 * 60 * 60 * 1000),
});
Some notes on this solution: On the client when you add the credentials: "include", you NEED to also add the cors on the backend otherwise nothing will work, however if you remove both they will communicate fine just without cookies. Also if you add the cors and not the include nothing will break but you will not receive the cookies.
Finally this post helped me find the solution, however I did not need to setup express middleware or use apollo-link-http library as you can see above in my solution, however the post may still be helpful.
I have issue with call online API from client.
I created nestjs API with httponly credential and when
nestjs app hosted in local and client from local it's worked
also when nestjs app hosted in online server and client hosted in online server it's worked
but when nestjs hosted in online server and client call API from local get forbidden error.
nestjs main.ts:
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '#nestjs/common';
// eslint-disable-next-line #typescript-eslint/no-var-requires
const cookieSession = require('cookie-session');
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
credentials:true,
origin:['http://localhost:3000','http://test.nextu.top']
});
app.use(
cookieSession({
keys: ['asdasd'],
}),
);
app.useGlobalPipes(new ValidationPipe());
await app.listen(5072);
}
bootstrap();
client fetch:
const doLogin = async () => {
const bData = {
Email: '********',
Password: '****'
}
fetch("http://api.nextu.top:5072/auth/signin", {
method: "POST",
body: JSON.stringify(bData),
headers: {
"access-control-allow-origin": "*",
'Content-Type': 'application/json;charset=UTF-8',
},
credentials: 'include'
}).then(res => res.json()).then(data => {
console.log(data);
getUserInfo();
})
}
const getUserInfo = () => {
fetch('http://api.nextu.top:5072/auth/userinfo', {
method: 'GET',
headers: {
"access-control-allow-origin": "*",
'Content-Type': 'application/json;charset=UTF-8',
},
credentials: 'include'
}).then(res => res.json()).then(data => console.log(data)).catch(err => console.log(err))
}
doLogin() working fine in each situation
getUserInfo() don't work when call from client and nestjs app hosted in online server
getUserInfo() has AuthGurd in nestjs
getUserInfo() working fine in postman
forbiden error :
I find a way to solve it:
changed from:
cookieSession({
keys: ['asdasd']
}),
);
to:
app.use(
cookieSession({
keys: ['asdasd'],
sameSite: 'none'
}),
);
and run client and server on https.
sameSite: 'none' just work on https mode
You should define on which domain the cookie is set, like so
app.use(cookieSession({
keys: ['asdasd'],
sameSite: 'strict',
domain:'.nextu.top'
}));
Note that the '.' is very important as it tell that cookie can be set on any subdomains of "nextu.top"
It work as expected on dev because your front and back are on the same domain "localhost", the only thing changing is the port, but on prod your front is "test.nextu.top" and back "api.nextu.top" which are not the same and cause your issue
I am working on a create-react-app that queries an API that requires a self-signed certificate to validate the request. I am grabbing the certificate through a GET request and using a helper to create a new Agent. My initial solution was to assign the httpsAgent in axios.interceptor to attach the certificate to every axios call.
But from what I understand the httpsAgent object is not being passed correctly to index.js because index.js runs in the browser and https is a core node module.
Is there a browser equivalent to https or an alternative method to sending the certificate to the back end? I saw a suggestion to proxy API requests and add the certificate that way, but I am unsure if that's the way to proceed.
Thanks so much!!
httpsAgent.js
const https = require('https');
const createAgent = (data) => {
const httpsAgent = new https.Agent({
ca: data,
rejectUnauthorized: true,
checkServerIdentity() {
return undefined;
},
});
return httpsAgent;
};
index.js
axios
.get('/certificate.pem')
.then(({ data }) => {
httpsAgent = createAgent(data);
})
.catch((err) => {
console.log(err);
})
.finally(() => {
axios.interceptors.request.use((config) => {
const newConfig = {
...config,
httpsAgent,
};
return newConfig;
});
});
I am using Express for my Back end of my React app when i set a session in a page and redirect to another page of my web app the session deleted
Here my express code :
async function createUser(req, res, next) {
try {
let parameters = req.body
let user = await models.User.create({
displayName: parameters.displayName,
phone: parameters.phone,
sex: parameters.sex,
password: parameters.password,
})
req.session.user = user.dataValues;
res.json({
status: 'success',
user,
})
}
and here is my react code :
onSubmit = (event) => {
event.preventDefault()
request.post('/newuser',{
displayName:this.state.name,
phone:this.state.phone,
password:this.state.password,
sex:this.state.sex
})
.then(function(response){
this.props.authenticate(true)
this.setState({
auth:true
})
}.bind(this))
}
and here is my react render method:
render(){
if(this.state.auth)
return <Redirect to='/profile' />;
}
with all this describes when i redirected to the profile page i dont have any session and all hope is gone :))
please help me solve this problem .
When you use axios for sending request you should do this :
In Front (React) :
You should set withCredentials: true in axios setting like this :
import axios from 'axios'
import config from '../../config'
const request = axios.create({
baseURL: config.url,
timeout: 20000,
withCredentials: true,
});
export default request
In Back (Node/Express) : you should add this code the the cors
const express = require('express')
const cors = require('cors')
app.use(cors({
origin:['http://localhost:9520']//your front url,
methods:['GET','POST'],
credentials: true
}))
I figured it out by searching, Thanks for not helping though :))
First of all I would like to say that I am new in senecajs.
I am testing this configuration.
I have configured Senecjs microservice running on port 9007, which is running and handling request correctly. When I request this service directly I receive response after cca 10s (it is request for oracle db data).
But when I request for same data but through the Hapi + Seneca-web I receive this error: "statusCode":504,"error":"Gateway Time-out"
["client","invalid_origin",{"port":9007,"pin":"mc:bankgtw","pg":"mc:bankgtw","type":"web","id":"pg:mc:bankgtw,pin:mc:bankgtw,port:9007","role":"transport","hook":"client","plugin$":{"name":"client$"},"fatal$":true,"meta$":{"mi":"wbn8u45tb7uh","tx":"o3f8eyia3f4n","id":"wbn8u45tb7uh/o3f8eyia3f4n","pattern":"hook:client,role:transport,type:web","action":"(q1yytemztu3k)","plugin_name":"transport","plugin_tag":"-","prior":{"chain":[],"entry":true,"depth":0},"start":1487199713842,"sync":true},"tx$":"o3f8eyia3f4n","host":"0.0.0.0","path":"/act","protocol":"http","timeout":5555,"max_listen_attempts":11,"attempt_delay":222,"serverOptions":{}},{"kind":"res","res":null,"error":{"isBoom":true,"isServer":true,"output":{"statusCode":504,"payload":{**"statusCode":504,"error":"Gateway Time-out**","message":"Client request timeout"},"headers":{}}},"sync":true,"time":{"client_recv":1487199799177}}]
A few seconds before microservice return data.
And this is my configuration:
const Hapi = require('hapi');
const Seneca = require('seneca');
const SenecaWeb = require('seneca-web');
const config = {
adapter: require('seneca-web-adapter-hapi'),
context: (() => {
const server = new Hapi.Server();
server.connection({
port: 3001,
routes: {
cors: true,
payload:{timeout:60000},
timeout:{server: 60000, socket:90000}
}
});
server.route({
path: '/routes',
method: 'get',
handler: (request, reply) => {
const routes = server.table()[0].table.map(route => {
return {
path: route.path,
method: route.method.toUpperCase(),
description: route.settings.description,
tags: route.settings.tags,
vhost: route.settings.vhost,
cors: route.settings.cors,
jsonp: route.settings.jsonp,
server: server.info
}
})
reply(routes)
}
});
return server;
})()
};
const seneca = Seneca({timeout: 99999})
.use(SenecaWeb, config)
.use(require('./hapi_api.js'))
.client({ port:9007, pin:'mc:bankgtw' })
.ready(() => {
const server = seneca.export('web/context')();
server.start(() => {
server.log('server started on: ' + server.info.uri);
});
});
What I am doing wrong or what timeout is causing this?
I've had the same issue, fixed it, but its VERY BAD PRACTICE.
Go to 'transport.js' at seneca-transport folder.
You will see 'timeout: 5555'
Go ahead and change that to whatever you need.
I'm not sure why this is not getting USER defaults.
To the best of my knowledge, this is referring to client timeout. make sure you still use server timeout.