Reputation: 8085
I can't make a simple connection to the server for some reason. I install the newest MySQL Community 8.0 database along with Node.JS with default settings.
This is my node.js code
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
Below is the error found in Command Prompt:
C:\Users\mysql-test>node app.js
C:\Users\mysql-test\node_modules\mysql\lib\protocol\Parse
r.js:80
throw err; // Rethrow non-MySQL errors
^
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
at Handshake.Sequence._packetToError (C:\Users\mysql-
test\node_modules\mysql\lib\protocol\sequences\Sequence.js:52:14)
at Handshake.ErrorPacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\sequences\Handshake.js:130:18)
at Protocol._parsePacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\Protocol.js:279:23)
at Parser.write (C:\Users\mysql-test\node_modules\mys
ql\lib\protocol\Parser.js:76:12)
at Protocol.write (C:\Users\mysql-test\node_modules\m
ysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:103:28)
at Socket.emit (events.js:159:13)
at addChunk (_stream_readable.js:265:12)
at readableAddChunk (_stream_readable.js:252:11)
at Socket.Readable.push (_stream_readable.js:209:10)
--------------------
at Protocol._enqueue (C:\Users\mysql-test\node_module
s\mysql\lib\protocol\Protocol.js:145:48)
at Protocol.handshake (C:\Users\mysql-test\node_modul
es\mysql\lib\protocol\Protocol.js:52:23)
at Connection.connect (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:130:18)
at Object.<anonymous> (C:\Users\mysql-test\server.js:
11:5)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
I've read up on some things such as: https://dev.mysql.com/doc/refman/5.5/en/old-client.html https://github.com/mysqljs/mysql/issues/1507
But I am still not sure how to fix my problem.
Upvotes: 798
Views: 1163295
Reputation: 660
For my case just changing the driver class name in configuration
from com.mysql.jdbc.Driver to com.mysql.cj.jdbc.Driver
works for me .
Upvotes: 0
Reputation: 310
in case you come accross this question and your stuff is at Digitalocean:
You can add a legacy user using MySQL 5+ encryption
Voilá
Upvotes: 0
Reputation: 4248
If you ran into this issue but continued to wish to utilise version 8 of MySQL
, you can. When creating the database using Docker
, you can accomplish this by instructing MySQL Server to implement the legacy authentication plugin.
Thus, your compose
file will appear as follows:
# Use root/example as user/password credentials
version: '3.1'
services:
db:
image: mysql:8.0.15
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'pass'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'pass'
ports:
- 3318:3306
# Change this to your local path
volumes:
- ~/Database/ORM_Test:/var/lib/mysql
Upvotes: 28
Reputation: 9008
The cleanest solution is to do the below command, and this issue will go away:
npm uninstall mysql
npm install mysql2
And then use it normally in your code:
var mysql = require('mysql2');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
I did not have any MySQL client in my system, but my docker container
had an image, which was giving me this issue. Simply installing the mysql2
resolved the issue.
You can find the solution here as well, mentioned in the official mysql
npm packages issues' answers. All the best.
Upvotes: 26
Reputation: 30097
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
and then flush privileges
mysql2
(instead of mysql
) and use it -- npm i mysql2
, and mysql = require('mysql2');
.Let's first make it clear what's going on.
MySQL 8 has supports pluggable authentication methods. By default, one of them named caching_sha2_password
is used rather than our good old mysql_native_password
(source). It should be obvious that using a crypto algorithm with several handshakes is more secure than plain password passing that has been there for 24 years!
Now, the problem is mysqljs
in Node (the package you install with npm i mysql
and use it in your Node code) doesn't support this new default authentication method of MySQL 8, yet. The issue is in here: https://github.com/mysqljs/mysql/issues/1507 and is still open, after 3 years, as of July 2019.
UPDATE June 2019: There is a new PR in mysqljs now to fix this!
UPDATE Feb 2020: Apparently it's scheduled to come in version 3 of mysqljs.
UPDATE July 2020: Apparently it's still not in yet (as of April 2020 at least), but it's claimed that node-mysql2 is supporting Authentication switch request. Please comment below if node-mysql2
is working fine for this issue -- I will test it later myself.
UPDATE April 2021: It seems like the issue is still there and just 3 days ago, someone created a fork and made it there -- yet not official in the mysql.js package. Also, as per the comments below, it seems like mysql2 package is working fine and supporting Authentication-switch properly.
That's what everybody suggests here (e.g. top answer above). You just get into mysql
and run a query saying root
is fine using old mysql_native_password
method for authentication:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password ...
The good thing is, life is going to be simple and you can still use good old tools like Sequel Pro without any issue. But the problem is, you are not taking advantage of a more secure (and cool, read below) stuffs available to you.
MySQL X DevAPI for Node is a replacement to Node's Mysqljs package, provided by http://dev.mysql.com official guys.
It works like a charm supporting caching_sha2_password
authentication. (Just make sure you use port 33060
for X Protocol communications.)
The bad thing is, you have left our old mysql
package that everyone is so used to and relies on.
The good thing is, your app is more secure now and you can take advantage of a ton of new things that our good old friends didn't provide! Just check out the tutorial of X DevAPI and you'll see it has a ton of new sexy features that can come in handy. You just need to pay the price of a learning curve, which expectedly comes with any technology upgrade. :)
PS. Unfortunately, this XDevAPI Package doesn't have types definition (understandable by TypeScript) yet, so if you are on typescript, you will have problems. I tried to generate .d.ts using dts-gen
and dtsmake
, but no success. So keep that in mind.
As mentioned above, mysql package (NPM package link) is still having this issue (as of April 2021). But mysql2 package (NPM package link) is not. So probably the following should be the one-liner answer!
npm un mysql && npm i mysql2
Please note that mysql2
is a forked work off of the popular mysql
, but its popularity (620K downloads per week for mysql2
in April 2020) has got close to the original package (720K download per week for mysql
in April 2021) that making the switch seems reasonable!
Upvotes: 815
Reputation: 278
If you're on Mac OS, and would like to use the legacy password encryption without using terminal.
Go to System Settings -> Find "My SQL" -> Click "Initialize Database" -> Select "Use legacy password encryption" and enter your database user password in the textfield and click "Ok"
Upvotes: 0
Reputation: 577
simple i uninstall mysql and install mysql2 for this issues and problem solved.
npm uninstall mysql && npm i mysql2
Upvotes: 5
Reputation: 2269
you should use whatever schema you use for your mysql connection for your session
(async () => {
const connection = await db.connection();
sessionStore = new MySQLStore({
}, connection); //just pass your connection here
})();
I just copy paste this here but your probably have implemented something similar to this to deal with your queries
const mysql = require('mysql')
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
require('dotenv').config();
}
const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
connectionLimit: process.env.DB_CONNECTION_LIMITS
}
const pool = mysql.createPool(dbConfig);
const connection = () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
reject(err);
}
const query = (sql, binding) => {
return new Promise((resolve, reject) => {
connection.query(sql, binding, (err, result) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};
const release = () => {
return new Promise((resolve, reject) => {
if (err) {
reject(err);
}
resolve(connection.release());
});
};
resolve({ query, release });
});
});
};
const query = (sql, binding) => {
return new Promise((resolve, reject) => {
pool.query(sql, binding, (err, result, fields) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};
module.exports = { pool, connection, query };
Upvotes: -1
Reputation: 696
Downgrading might not be a good option as:
You can use mysql2
package in place of mysql
. Its mostly API compatible with mysqljs.
Also, it has promises support.
Use it like:
const mysql = require('mysql2/promise')
(for promise based methods)
You can read more about mysql2
here: https://www.npmjs.com/package/mysql2
Upvotes: 9
Reputation: 19180
Execute the following query in MYSQL Workbench
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
Where root
as your user
localhost
as your URL
and password
as your password
Then run this query to refresh privileges:
flush privileges;
Try connecting using node after you do so.
If that doesn't work, try it without @'localhost'
part.
Upvotes: 1906
Reputation: 101
For MySql 8 instead of changing the authentication for the root user create a new user with all privileges and change the authentication method from caching_sha2_password to mysql_native_password. Please check the documentation by Ochuko Ekrresa for detailed steps.
Summary of Steps:
mysql -u root -p
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'localhost';
Check the above-mentioned document link to get details on giving specific privileges.
FLUSH PRIVILEGES;
quit;
and login again with mysql -u [newuser] -p;
ALTER USER 'newuser'@'localhost' IDENTIFIED WITH mysql_native_password by 'password';
Additional Info: For me after changing authentication for root, I was faced with Authentication issues and was unable to login. So I reset my password(Reset password doc).
Upvotes: 8
Reputation: 4652
UPDATE mysql.user SET authentication_string = PASSWORD('MY_NEW_PASSWORD')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;
This worked for me.
Upvotes: 0
Reputation: 10296
And you have good to go with caching_sha2_password
auth method.
Query with Knex:
const response = await knex.raw("SELECT * FROM USERS");
OR
If you don't have a remote user then use CREATE
keyword instead of ALTER
and just put the below command on the terminal.
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'@'%';
Flush privileges;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'@'localhost';
Flush privileges;
All done :)
Upvotes: 2
Reputation: 371
Simplest answer is :-
install mysql2 in node
Don't downgrade your mysql db.
You are good to go. Happy Coding!
Upvotes: 26
Reputation: 3766
If you have access to create a new user privilege then do so to connect normally with node.js, that is worked for me
Upvotes: 0
Reputation: 93
I had this error for several hours an just got to the bottom of it, finally. As Zchary says, check very carefully you're passing in the right database name.
Actually, in my case, it was even worse: I was passing in all my createConnection()
parameters as undefined
because I was picking them up from process.env
. Or so I thought! Then I realised my debug and test npm scripts worked but things failed for a normal run. Hmm...
So the point is - MySQL seems to throw this error even when the username, password, database and host fields are all undefined
, which is slightly misleading..
Anyway, morale of the story - check the silly and seemingly-unlikely things first!
Upvotes: 0
Reputation: 1256
I just run into this problem too, with all the MySQL re-config mentioned above the error still appears. It turns out that I misspelled the database name.
So be sure you're connecting with the right database name especially the case.
Upvotes: 3
Reputation: 624
For existing mysql 8.0 installs on Windows 10 mysql,
launch installer,
click "Reconfigure" under QuickAction (to the left of MySQL Server), then
click next to advance through the next 2 screens until arriving
at "Authentication Method", select "Use Legacy Authentication Method (Retain MySQL 5.x compatibility"
Keep clicking until install is complete
Upvotes: 5
Reputation: 101
You can skip the ORM, builders, etc. and simplify your DB/SQL management using sqler
and sqler-mdb
.
-- create this file at: db/mdb/read.table.rows.sql
SELECT TST.ID AS "id", TST.NAME AS "name", NULL AS "report",
TST.CREATED_AT AS "created", TST.UPDATED_AT AS "updated"
FROM TEST TST
WHERE UPPER(TST.NAME) LIKE CONCAT(CONCAT('%', UPPER(:name)), '%')
const conf = {
"univ": {
"db": {
"mdb": {
"host": "localhost",
"username":"admin",
"password": "mysqlpassword"
}
}
},
"db": {
"dialects": {
"mdb": "sqler-mdb"
},
"connections": [
{
"id": "mdb",
"name": "mdb",
"dir": "db/mdb",
"service": "MySQL",
"dialect": "mdb",
"pool": {},
"driverOptions": {
"connection": {
"multipleStatements": true
}
}
}
]
}
};
// create/initialize manager
const manager = new Manager(conf);
await manager.init();
// .sql file path is path to db function
const result = await manager.db.mdb.read.table.rows({
binds: {
name: 'Some Name'
}
});
console.log('Result:', result);
// after we're done using the manager we should close it
process.on('SIGINT', async function sigintDB() {
await manager.close();
console.log('Manager has been closed');
});
Upvotes: 0
Reputation: 357
In addition to the above answers ; After executing the below command
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
If you get an error as :
[ERROR] Column count of mysql.user is wrong. Expected 42, found 44. The table is probably corrupted
Then try in the cmd as admin; set the path to MySQL server bin folder in the cmd
set path=%PATH%;D:\xampp\mysql\bin;
and then run the command :
mysql_upgrade --force -uroot -p
This should update the server and the system tables.
Then you should be able to successfully run the below commands in a Query in the Workbench :
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'
then remember to execute the following command:
flush privileges;
After all these steps should be able to successfully connect to your MySQL database. Hope this helps...
Upvotes: 3
Reputation: 930
If you are using docker, it worked for me!
in the docker-compose.yml
add the following lines:
mysql:
...
command: --default-authentication-plugin=mysql_native_password
restart: always
after that, down
the container and up
again.
Upvotes: 6
Reputation: 725
Just figured this out after trying numerous things. What finally did it for me was adding require('dotenv').config()
to my .sequelizerc
file. Apparently sequelize-cli doesn't read env variables.
Upvotes: 0
Reputation: 786
With MySQL 8+ the new default authentication is caching_sha2_password
instead of mysql_native_password
. The new and more secure authentication method is not supported by the native mysql
package yet, but you should consider using the package @mysql/xdevapi
instead, which is officially supported and maintained by Oracle.
To install the new package, run:
npm install @mysql/xdevapi --save --save-exact
To connect to the database and INSERT some VALUES:
const mysqlx = require('@mysql/xdevapi');
var myTable;
mysqlx
.getSession({
user: 'root',
password: '*****',
host: 'localhost',
port: 33060
})
.then(function (session) {
// Accessing an existing table
myTable = session.getSchema('Database_Name').getTable('Table_Name');
// Insert SQL Table data
return myTable
.insert(['first_name', 'last_name'])
.values(['John', 'Doe'])
.execute()
});
The official package documentation can be found here: https://dev.mysql.com/doc/dev/connector-nodejs/8.0/
Upvotes: 4
Reputation: 1498
In MySQL 8.0,
caching_sha2_password
is the default authentication plugin rather thanmysql_native_password. ...
Most of the answers in this question result in a downgrade to the authentication mechanism from caching_sha2_password
to mysql_native_password
. From a security perspective, this is quite disappointing.
This document extensively discusses caching_sha2_password
and of course why it should NOT be a first choice to downgrade the authentication method.
With that, I believe Aidin's answer should be the accepted answer. Instead of downgrading the authentication method, use a connector which matches the server's version instead.
Upvotes: 7
Reputation: 279
If the ALTER USER ... command line doesn't work for you AND if you are using Windows 10 then try to follow those steps:
1) Type MySQL in the windows search bar
2) Open the MySQL Windows Installer - Community
3) Look for "MySQL server" and click on Reconfigure
4) Click on "Next" until you reach the "Authentification Method" phase
5) On the "Authentification Method" phase check the second option "Use Legacy Authentication Method"
6) Then follow the steps given by the Windows installer until the end
7) When it's done, go into "Services" from the Windows search bar, click on "start" MySql81".
Now, try again, the connection between MySQL and Node.js should work!
Upvotes: 21
Reputation: 529
Check privileges and username/password for your MySQL user.
For catching errors it is always useful to use overrided _delegateError
method. In your case this has to look like:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});
var _delegateError = con._protocol._delegateError;
con._protocol._delegateError = function(err, sequence) {
if (err.fatal)
console.trace('MySQL fatal error: ' + err.message);
return _delegateError.call(this, err, sequence);
};
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
This construction will help you to trace fatal errors.
Upvotes: 0
Reputation: 6153
$ mysql -u root -p
Enter password: (enter your root password)
(Replace your_new_password
with the password you want to use)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
mysql> FLUSH PRIVILEGES;
mysql> quit
Then try connecting using node
Upvotes: 53
Reputation: 465
I have MYSQL on server and nodejs application on another server
Execute the following query in MYSQL Workbench
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password'
Upvotes: 4
Reputation: 593
Although the accepted answer is correct, I'd prefer creating a new user and then using that user to access the database.
create user nodeuser@localhost identified by 'nodeuser@1234';
grant all privileges on node.* to nodeuser@localhost;
ALTER USER 'nodeuser'@localhost IDENTIFIED WITH mysql_native_password BY 'nodeuser@1234';
Upvotes: 28