Error: Access denied for user ''#'localhost' (using password: NO) - mysql

I'm trying out db migrations with MySQL and Knex.
When I run the command knex migrate:latest, I get
ER_ACCESS_DENIED_ERROR: Access denied for user ''#'localhost' (using password: NO)
I've tried adding a password on the codebase (to '123' and 'NO'), though what confuses me most is that even as I have user: "root" in my database file, the error gives an empty string as the user...
I share what I imagine are the pertinent files:
// mysql_db.js
const knex = require('knex')({
client: 'mysql',
connection: {
host: 'localhost',
user: 'root',
password: '',
database: 'SQL_Data',
},
});
module.exports = knex;
// knexfile.js
const path = require('path');
module.exports = {
development: {
client: 'mysql',
connection: {
filename: '/server/SQL/mysql_db',
},
migrations: {
directory: path.join(__dirname, '/server/SQL/migrations'),
},
seeds: {
directory: path.join(__dirname, '/server/SQL/seeds'),
},
},
};
//knex.js
const environment = proces.env.NODE_ENV || 'development';
const config = require('../../knexfile.js')[environment];
module.exports = require(knex)('config');
// "migration definition"
exports.up = (knex, Promise) => knex.schema.createTable('sql_table', ((table) => {
table.increments();
table.string('name').notNullable();
table.string('email').notNullable();
table.string('description').notNullable();
table.string('url').otNullable();
}));
exports.down = (knex, Promise) => knex.schema.dropTable('sql_table');

As error message say you are trying to login with invalid credentials user whose name is empty string doesn't exist in DB.
This means your configuration is wrong. you have some strange segment in your node-mysql driver configuration, which tries to refer other file, which exports initialized knex instance
client: 'mysql',
connection: {
filename: '/server/SQL/mysql_db'
}
That is just plain wrong. Correct format for knexfile is pretty much the same that is used to create knex instance, except that knexfile supports also selecting the profile according to NODE_ENV environment variable.
const path = require('path');
module.exports = {
development: {
client: 'mysql',
connection: {
host: 'localhost',
user: 'root',
password: '',
database: 'SQL_Data',
},
migrations: {
directory: path.join(__dirname, '/server/SQL/migrations'),
},
seeds: {
directory: path.join(__dirname, '/server/SQL/seeds'),
},
},
};
In your mysql_db you might like to do something like this to init knex to
be able to use the same config:
const knex = require('knex')(
require('knexfile')[process.env.NODE_ENV || 'development']
);

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;

why sequelize-cli is not loading config variables?

I tried searching for the answer, closest question i got was Sequelize CLI Not Finding Env Variables.
I compared my code and it was exactly like the answer provided, then just to debug i edited config file to set values manually instead of reading from .env but sequelize-cli still gives same error
ERROR: SequelizeDatabaseError: Access denied for user ''#'localhost' to database 'dbname'
at Query.formatError (/home/name/Documents/nodejs/project/db/node_modules/sequelize/lib/dialects/mysql/query.js:265:16)
at Query.run (/home/name/Documents/nodejs/project/db/node_modules/sequelize/lib/dialects/mysql/query.js:77:18)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async /home/name/Documents/nodejs/project/db/node_modules/sequelize/lib/sequelize.js:619:16
at async Object.exports.handler (/home/name/Documents/nodejs/project/db/node_modules/sequelize-cli/lib/commands/database.js:49:7)
Here is my config.js file
require("dotenv").config();
console.log(process.env.NODE_ENV, "it is being loaded correctly");
const config = {
development: {
username: "mysql",
password: "",
database: "dbname",
host: "localhost",
port: "3306",
dialect: "mysql",
dialectOptions: {
charset: "utf8mb4",
},
},
production: {
username: "mysql",
password: "",
database: "dbname",
host: "localhost",
port: "3306",
dialect: "mysql",
dialect: "mysql",
dialectOptions: {
charset: "utf8mb4",
},
},
};
console.log(config);
module.exports = config;
and lastly here is .sequelizerc file
const path = require('path');
module.exports = {
'config': path.resolve('config', 'config.js')
}
Funny thing is this project was working perfectly on my last computer (macos) and my server(ubuntu) but i am facing this issue with ubuntu desktop. AFAIK it should not be an operating system problem.
here is models/index.js
"use strict";
require("dotenv").config();
const fs = require("fs");
const path = require("path");
const Sequelize = require("sequelize");
const basename = path.basename(__filename);
const env = process.env.NODE_ENV;
console.log(env);
const config = require(__dirname + "/../config/config")[env];
const db = {};
console.log("config check", config);
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
);
}
fs.readdirSync(__dirname)
.filter((file) => {
return (
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
);
})
.forEach((file) => {
const model = require(path.join(__dirname, file))(
sequelize,
Sequelize.DataTypes
);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
UPDATE 1:
I have tried to connect to database programmatically and get same error.
original: Error: Access denied for user ''#'localhost' to database 'dbname'
at Packet.asError (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/packets/packet.js:712:17)
at ClientHandshake.execute (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/commands/command.js:28:26)
at Connection.handlePacket (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/connection.js:425:32)
at PacketParser.onPacket (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/connection.js:75:12)
at PacketParser.executeStart (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/packet_parser.js:75:16)
at Socket.<anonymous> (/home/user/Documents/nodejs/project/db/node_modules/mysql2/lib/connection.js:82:25)
at Socket.emit (events.js:400:28)
at addChunk (internal/streams/readable.js:290:12)
at readableAddChunk (internal/streams/readable.js:265:9)
at Socket.Readable.push (internal/streams/readable.js:204:10) {
code: 'ER_DBACCESS_DENIED_ERROR',
errno: 1044,
sqlState: '42000',
sqlMessage: "Access denied for user ''#'localhost' to database 'dbname'"
A couple of shots in the dark: If you try to connect with a blank password you need to set the password param to null in the connection configuration:
const sequelize = new Sequelize('database', 'username', null, {
dialect: 'mysql'
})
Also, as mentioned in a comment, it looks like it can't set your username correctly, so it turns out as an empty string ('') in the error msg.
Maybe you have switched around username and password in the config object for Sequelize so the empty password becomes the username?
Will update this answer if I get better ideas when you show the connection code :)
EDIT 1:
Seems to be something fishy about your config in new Sequelize(process.env[config.use_env_variable], config);
It should have four parameters, here you have added the username and password into the config object. There should be three string params (or null) and one config object, four in total.

I can't connect to mysql database using process.env.variable

my config.env file
PORT=5000
DB_HOST='localhost'
DB_PORT=3306
DB_USER='root'
DB_PASSWORD='fast'
DB_NAME='hms'
my dbconnect file(in same directory as config.env file)
I cannot connect using process.env but if I directly type values like I have did in commented code then it will connect to database. Also if I console.log values of process.env.anyvariable then I will get the correct value of env variable but if i assign it to some variable like suppose const variable=process.env.DB_HOST then it will be undefined in console.log. It is throwing me this error
code: 'ER_ACCESS_DENIED_ERROR',
errno: 1045,
sqlMessage: "Access denied for user ''#'localhost' (using password: NO)",
sqlState: '28000',
fatal: true
const mysql = require("mysql")
const dotenv = require("dotenv")
dotenv.config({ path: './config.env' });
const connection = mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
})
// const connection = mysql.createConnection({
// host: 'localhost',
// port: 3306,
// user: 'root',
// password: 'fast',
// database: 'hms'
// })
connection.connect( (err) => {
if (err){
console.log(err)
}
else
{
console.log("Database connected!")
}
})
my /config/config.env is not in the parent directoy so instead of
dotenv.config({ path: './config.env' });
write
dotenv.config({ path: __dirname + '/config.env' });

How to renew connection of database for iam authentication

Using IAM database authentication the password expires after about 15 minutes. So I ideally have to renew the database connection before the password expires. I set up a timer on the first initialization of the database and query the passed time on each query. How can i refresh the password of the connection before the password expires? Or how can i destroy the old database object and renew the object if necessary?
The error message is: "PAM authentication failed for user iam_user".
code for getting IAM Password:
const pgp = require('pg-promise')();
const AWS = require('aws-sdk');
const ca =
'-----BEGIN CERTIFICATE-----\nMIID9DCCAtyg...
...wZfTUU=\n-----END CERTIFICATE-----\n';
const signer = new AWS.RDS.Signer({
region: process.env.REGION,
username: process.env.DATABASE_USER,
hostname: process.env.DATABASE_HOST,
port: parseInt(`${process.env.DATABASE_PORT}`, 10),
});
module.exports = pgp({
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
database: process.env.DATABASE_NAME,
user: process.env.DATABASE_USER,
ssl: { ca },
dialectOptions: { ssl: { require: true } },
password: signer.getAuthToken(),
});
injecting db object to graphql:
const db = require('../db/init');
server.use(
mount(
'/graphql',
graphqlHTTP( () => ({
schema: schema,
context: { startTime: Date.now(), db },
graphiql: true
})),
),
);
Using the database in the resolvers.
I could query the time of the creation of the database connection. Is there a possibility to renew the password if necessary? Or what is the best way to destroy the old database object and create a new database object?
const resolvers = {
Query: {
Post: (root, args, {db}) => {
console.log(args.id);
console.log(db.$config.options)
const postQuery = new PQ({
text:
'SELECT post_id as id FROM tbl_post where post_id = $1',
values: [parseInt(args.id, 10)],
});
return db.one(postQuery).catch((err) => console.log(err));
}
}
As suggested by vitaly-t i used a password function. To avoid adding latency this functions renews the password only every 15 minutes. If the pool gets continuously used in intervals lower than 10 seconds, than the connection stays open without calling the password function at all. According to my tests there are no new connections to the database opened at all.
const ca = '-----BEGIN CERTIFICATE-----\9DC...-----END CERTIFICATE-----\n';
const signer = new AWS.RDS.Signer({
region: process.env.REGION,
username: process.env.DATABASE_USER,
hostname: process.env.DATABASE_HOST,
port: parseInt(`${process.env.DATABASE_PORT}`, 10),
});
const SIGNER = { time: 0, password: undefined};
function getSignedPassword() {
const time = Date.now();
if (time - SIGNER.time > 900000) {
SIGNER.time = new Date().getTime();
SIGNER.password = signer.getAuthToken();
return SIGNER.password;
}
return SIGNER.password;
}
module.exports = pgp({
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT,
database: process.env.DATABASE_NAME,
user: process.env.DATABASE_USER,
ssl: { ca },
password: getSignedPassword,
});

bug with angular2-meteor app :failed connection to mysql via meteor

i'm trying to connect to mysql database with meteor using nodets:mysql and i'm facing this error :
Unhandled rejection Error: No infromation can be fetched by your database, please check your permissions
this is my part of code :
Meteor.startup(function() {
//Start of changes
var connectionSettings = {
host: '127.0.0.1',
user: 'root',
password: '',
database: 'test'
};
var db = Mysql.connect(connectionSettings);
})
i need to add the port of mysql
Meteor.startup(function() {
//Start of changes
var connectionSettings = {
host: '127.0.0.1',
port : (mysqlport),
user: 'root',
password: '',
database: 'test'
};
var db = Mysql.connect(connectionSettings);
})