Nodejs - unable to load environment variable in mysql2 - mysql

I am using the mysql2 package for connecting node with MySQL and I am using a .env file to store my username and password. But when I use it in my config for connecting MySql it doesn't load. It throws the following error whenever I hit an endpoint using Postman.
Error: Access denied for user 'undefined'#'localhost' (using password: YES)
Below is my code:
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const connection = mysql.createPool({
user: `${process.env.DB_USERNAME}`,
host: "localhost",
password: `${process.env.DB_PASSWORD}`,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
database: "issue",
});
I am using dotenv to load env variables and initialized in my entry file as:
require('dotenv').config();
What am I doing wrong?

As a side effect of the way JavaScript coerces types, process.env.foo will result in "undefined" if it is undefined and used in a string.
There is either a typo in your dotenv config file or else some other problem with your use of dotenv.
I would recommend more defensive coding to give a better error message when this happens. (The following code is untested, but you will no doubt get the idea.)
const express = require("express");
const router = express.Router();
const mysql = require("mysql2");
const dbUsername = process.env.DB_USERNAME;
const dbPassword = process.env.DB_PASSWORD;
if (!dbUsername) {
throw new Error('DB_USERNAME environment variables must be set');
}
if (!dbPassword) {
throw new Error('DB_PASSWORD environment variables must be set');
}
const connection = mysql.createPool({
user: dbUsername,
host: "localhost",
password: dbPassword,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
database: "issue",
});

Related

Access denied for user 'root#localhost'

I am currently working on a homework based on ORM. I finished my code however when I start my server, I get a access denied. I checked my credentials for my env file and its correct. I have attached the message from gitbash as well, my connection code to gain access to the database, and an env example of the credentials that are required. enter image description here
DB_NAME='ecommerce_db'
DB_USER=''
DB_PASSWORD=''
require('dotenv').config();
const Sequelize = require('sequelize');
const sequelize = process.env.JAWSDB_URL
? new Sequelize(process.env.JAWSDB_URL)
: new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PW, {
host: 'localhost',
dialect: 'mysql',
dialectOptions: {
decimalNumbers: true,
},
});
module.exports = sequelize;

Query a Google cloud SQL instance in Node.js from a GKE pod with cloud sql proxy running as sidecar

I am tasked with adding a MySql database to a microservice application for work. I am the only person on this task and don't really have anyone to turn too for advice so I am reaching out to the internets for help. I have succesfully deployed a pod that is running a small test application and the cloud-sql-proxy. I have scoured the documentation trying to figure out how to connect to the db and perform a query and this is what I have come up with (but it doesn't work).
const express = require('express');
const mysql = require('mysql');
const bodyParser = require('body-parser')
const cors = require('cors');
const axios = require('axios');
const app = express();
app.use(bodyParser.json());
app.use(cors())
app.enable('trust proxy');
// Automatically parse request body as form data.
app.use(express.urlencoded({extended: false}));
// This middleware is available in Express v4.16.0 onwards
app.use(express.json());
// [START cloud_sql_mysql_mysql_create_tcp]
const createTcpPool = async config => {
// Extract host and port from socket address
const dbSocketAddr = process.env.DB_HOST.split(':');
// Establish a connection to the database
return mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: dbSocketAddr[0], // e.g. '127.0.0.1'
port: dbSocketAddr[1], // e.g. '3306'
// ... Specify additional properties here.
...config,
});
};
// [END cloud_sql_mysql_mysql_create_tcp]
var pool = createTcpPool();
const stuff = pool.query('SELECT * FROM entries');
function getQuery() {
console.log(stuff);
}
getQuery()
Here is a picture of the error I get when I deploy the pod and the logs from the proxy to verify it's running
I'm pretty new to MySql and GKE and trying to figure this out has been a huge struggle. I just want to know how I can actually query the db and would greatly appreciate some assistance or code sample to point me in the right direction, thanks internets.
As mentioned in the thread1 ,
Handling such functions can be done through following example :
const mysql = require('mysql');
const pool = mysql.createPool({ connectionLimit : 1, socketPath: '/cloudsql/' + '$PROJECT_ID:$REGION:$SPANNER_INSTANCE_NAME',
user: '$USER', p
assword: '$PASS',
database: '$DATABASE' });
exports.handler = function handler(req, res)
{ //using pool instead of creating connection with function call
pool.query(`SELECT * FROM table where id = ?`,
req.body.id, function (e, results) {
//made reply here
}); };
For more information you can refer to the documentation related to TCP connection when using Node js.
const createTcpPool = async config => {
// Extract host and port from socket address
const dbSocketAddr = process.env.DB_HOST.split(':');
// Establish a connection to the database
return mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: dbSocketAddr[0], // e.g. '127.0.0.1'
port: dbSocketAddr[1], // e.g. '3306'
// ... Specify additional properties here.
...config,
});
};
So trying to create a pool by calling createTcpPool seems to have been the issue. I changed it to
let pool = mysql.createPool({
user: process.env.DB_USER, // e.g. 'my-db-user'
password: process.env.DB_PASS, // e.g. 'my-db-password'
database: process.env.DB_NAME, // e.g. 'my-database'
host: '127.0.0.1', // e.g. '127.0.0.1'
port: '3306'
});
and got a succesful return from my db.

"Access denied for user localhost (using password: NO)" when I use variables from .env file

I'm losing my mind on this one. I have my app.js which creates a connection to mysql. It works fine like this :
app.js
const path = require('path')
const hbs = require('hbs')
const express = require('express')
const mysql = require('mysql')
const app = express()
const port = process.env.PORT || 3000
const db = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "test"
});
db.connect((error) => {
if(error) throw error
console.log("MYSQL Connected")
})
But it doesn't work with this :
app.js
const path = require('path')
const hbs = require('hbs')
const express = require('express')
const dotenv = require('dotenv')
const mysql = require('mysql')
dotenv.config({ path: './.env' })
const app = express()
const port = process.env.PORT || 3000
const db = mysql.createConnection({
host: process.env.HOST,
user: process.env.USER,
password: process.env.PASSWORD,
database: process.env.DATABASE
});
db.connect((error) => {
if(error) throw error
console.log("MYSQL Connected")
})
.env
DATABASE = test
HOST = localhost
USER = root
PASSWORD = password
It recognizes the values I have stored in my .env file since my IDE is showing me the values when I type them in and as long the values of user & password are typed in app.js (but not host and database), it works.
I'm new to MySQL, never used it before, and I'm on Windows. So if I need to do some command lines, can you please specify in which terminal I should type them in ?
Can someone help me ?
Thank you !
Found the answer.
For some reason, this path :
dotenv.config({ path: './.env' })
Didn't work. I had to do it like this :
const path = require('path')
const dotenv = require('dotenv')
dotenv.config({ path: path.join(__dirname, './.env') })
I found this solution by using console.log() on the variables (process.env.HOST, etc...). They were undefined.
Conclusion : always console.log() your stuff.

mysql2/promise require database connection file

I have only been working with PHP before going to Node.JS. What I was able to do in PHP when working with MYSQL was that I could include the database.php file in the files I wanted to execure queries in.
It doesn't seem to be the same in Node.Js. This is my database.js file
const mysql = require("mysql2/promise");
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'XXXX',
database: 'nodelogin'
});
module.exports = db;
Then I require this in my file login.js
const db = require("../../database");
However, when I then try to run db.query(sql, [variable]) I get db.query is not a function.
Why is this? It shouldn't be that more complicated or should it?
If you use a connection pool instead, you can include the pool once, then call query on it, like so:
db-config.js
const mysql = require("mysql2/promise");
console.log("Creating connection pool...")
const pool = mysql.createPool({
host: 'localhost',
user: 'user',
database: 'test_db',
password: 'password'
})
module.exports = pool;
test.js
// Require to whereever db-config is
const pool = require('./db-config.js');
async function testQuery() {
const results = await pool.query("select * from users");
console.table(results[0]);
}
testQuery();

How to store db credentials for use on either heroku or development when using Nodejs

I have a db.js file in my node app which contains the credentials for the heroku database i'm using and the local database I'm using.
I want to a.stop having to manually comment out the credentials, as well as the ability to be able for the app to know when it's running on heroku (and therefore use the heroku credentials) Also i'm worried about security, I know I can just omit storing the db.js file from my github repo, but I'm not sure what the best practice for this is.
db.js file
var mysql = require('mysql');
var conn = {
development: {
conn : mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'test1'
})
},
// heroku credentials
production: {
conn : mysql.createConnection({
host: 'test.net',
user: 'test',
password: 'test',
database: 'heroku'
})
}
}
module.exports = conn;
How i'm calling it in my code
var env = process.env.NODE_ENV || 'development';
var conn = require('./db')[env];
and then using it like
let query = conn.query(sql, (err, results) => {
Which is giving me the following error
conn.query is not a function
You can set your env variables with Heroku cli
Exemple for your SQL user and password
$ heroku config:set SQL_PASSWORD=XXX
$ heroku config:set SQL_USER=John
And use it
production: {
conn : mysql.createConnection({
...
password: process.env.SQL_PASSWORD,
user: process.env.SQL_USER,
database: 'heroku'
})
Good to know: Heroku set automatically NODE_ENV=PRODUCTION
Look at this documentation: https://devcenter.heroku.com/articles/config-vars