Is it possible to use online databases in a local project? - remote-access

Here is my database connection:
// connect to database and select database
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "spy";
$dbh_conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$dbh_conn->exec("set names utf8");
$dbh_conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
It works fine since the database is exists in the local. Now I've uploaded the database on a server and I want to use that online database (instead of the local one). Is it possible? If yes, what should I write as servername?

Yes it is possible,
Tough I would suggest you to take down all these info you've submitted here and simply replace "localhost" to the Access host you've published.
You don't want people to know you've a sweet unsecured database at that IP :)
It's funny you underlined the answer ;)

Related

Getting 'Could not find stored procedure' error calling SQL Server stored procedure in Node JS from AWS RDS database

We always normally work in Azure where I write around 200 stored procedures a year in their SQL Server database.
We had to create a SQL Server database in AWS-RDS and still call it in our Node APIs like usual. I was able to quickly and easily set up the AWS DB in SQL Server Management Studio so I do know the credentials.
I created several tables and several stored procedures with no problems and tested to make sure they worked there. When I called them like I normally do in Node, I found I was getting an error
Could not find stored procedure
I went through forums all over but most of the data pertains to MySQL instead of SQL Server, and after trying everything I saw in the forums have not been able to complete what should be a very simple process. I would imagine there is some simple thing I missed, but after 2 days it is time for some fresh ideas.
I am setting up the credentials like this:
var awsConnection = {
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
port : process.env.RDS_PORT
};
I am using the endpoint provided by AWS for the host, the username and password I use to login to SQL Server Management Tool (which works). The port number is the one specified by AWS (1433 - the default for SQL Server).
I call it in my api like this:
await sql.connect(connectionAWS).then(pool => {
// Stored procedure
console.log("awsConnection INSIDE: " + JSON.stringify(awsConnection));
return pool.request()
.input('repId', sql.VARCHAR(40), repObj.RepID)
.execute('UserExistsBD');
}).then(async result => { ...
I added the console.log to see if we were getting past the login and it appears that we do. I also used Telnet to make sure the endpoint/port combo work and they do. I also checked AWS to make sure the Subnets, Route tables, and gateways were good and to make sure my IP Address was white listed. Any ideas would be very much appreciated!

ServiceStack.Redis authentication Redis Sentinel + Redis

The problem:
It is not obvious how to correctly authenticate with:
sentinels
redis instances themselves
when using the ServiceStack.Redis solution.
According to the docs a proper way to provide a password for redis/sentinel is to set it via URLs in the following manner:
var sentinel = new RedisSentinel(new[] {"password#localhost:26381"})
This works fine, but how do I provide a password for the redis connections themselves?
The password I've specified in the URL will not be copied over to redis connections.
I've found a workaround, that seems to be working, but I'm not sure if it will actually cover all the possible cases:
//Get the original factory
var clientFactory = RedisConfig.ClientFactory;
//Decorate it with the logic that sets a password.
RedisConfig.ClientFactory = c =>
{
c.Password = "password";
return clientFactory.Invoke(c);
};
//Continue to initialize sentinels
var sentinel = new RedisSentinel(new[] {"password#localhost:26379"});
It seems like this will actually fix the problem and will provide a password to the connections to redis instances (not sentinels).
The question is: is this the recommended way of doing it? Or is there a better approach?
You can use a RedisSentinel HostFilter to customize the connection string for the individual hosts the sentinel connects to, e.g:
sentinel.HostFilter = host => $"password#{host}";

MongoDB Docker URI does not have hostname, domain name and tld

I am trying to connect to my local MongoDB Database that is on docker with nodejs. My component are:
.env file
MONGODB_USERNAME = 'accountUser'
MONGODB_PASSWORD = 'password'
MONGODB_HOST = 'mongodb'
MONGODB_DATABASE = 'mydb'
Code:
const uri = `mongodb+srv://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}#${process.env.MONGODB_HOST}/${process.env.MONGODB_DATABASE}?retryWrites=true&w=majority`;
console.log(uri);
const client = new MongoClient(uri);
Console Output
mongodb+srv://accountUser:abc123#mongodb/mydb?retryWrites=true&w=majority
Error
MongoParseError: URI does not have hostname, domain name and tld
What can I be doing wrong?
You are trying to use an SRV URI when you should be using an ordirary URI.
SRV URIs have the additional security requirements on hostnames (that it contains 3 components minimum).
Remove +srv from your URI.
1). Go to the database, click edit password and generate a new password.
2). Go to the database, click edit password and give only characters and numbers.
If the username or password includes the following characters:
: / ? # [ ] #
You should simply replace those characters.
How to connect to MongoDB Atlas from a NestJS Application:
Under Deployment select Databases
Click on your database instance
Next to the name and status of the instance click Connect
Click Connect your application
Under DRIVER select Node.js
Under VERSION select 2.2.12 or later
Copy the full URI including all of the individual nodes and use that to connect instead
As D. SM said earlier you can't use a URI with +srv in it and rolling back the driver version is the only way to get a connection string generated without +srv.

MongoDB custom user roles - "user is not allowed(...)"

I created a free tier cluster on MongoDB Atlas (it has 3 shards) and I want my Node.js app to connect with a database I created there, using a specific user, that will be restricted from using any other database than the one inteded for this app.
So step by step.
I create a database called, let's say, test.
I create a role here - I go to Security -> MongoDB Roles -> Add New Custom Role and I give it all Collection actions and all Database actions and roles to test
Time for a user, so again Security -> MongoDB Users -> Add New User and I assign a previously created role to it so it has access only to test database. So now I have 2 users - atlasAdmin and my created user.
That's where the problem occurs, when I use admin user in my app to connect, .find() or .create() it works fine all the time. With a user with custom role, it works for like 10mins/1 connection (until I shut down the local server I have my node app on) and the next time I get an error that "user is not allowed to perform action (...)".
I tried everything, tinkering with a string I use to connect, updating mongoose (I use it in my app), creating user and custom role using mongodb shell but nothing seems to work.
HOWEVER:
if I have this custom user, my app connects with it to the database and it works, then on the next connection it stops working AND I go here and just click UPDATE USER without changing anything there (I just click edit next to the user and then update) then wait for the cluster to make changes, it will work again for like +/- one connection.
everything works just fine if my app uses admin account
Anyone had similar problem? Screenshot of the error I was also thinking that it might be because of how many times I try to connect with mongo from the app (I use nodemon so everytime I save a file with changes, server restarts, thus connecting to database again) but I think that's not the case - if it was, why would I be able to make it work with admin user?
The string I use to connect with mongo:
// DATABASE SETUP
var dbURL = 'mongodb://[cluster0:port],[cluster1:port],[cluster2:port]/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true';
var options = {
useNewUrlParser: true,
dbName: "test"
user: [login],
pass: [pass]
};
mongoose.connect(dbURL, options);
I have also encountered this problem on Atlas Free tier, not just on NodeJS but Java as well
For now, you can try mitigating this problem by using a default role instead of having a custom one
On the MongoDB Users tab, click "Edit" on your user => Add Default Privileges
Picture 1
Then select "readWrite" and type your database name on the first field, then save the user
Picture 2
Or, if you want database administration, add another field with "dbAdmin" role
Picture 3
At least that's how I solved it. I hope this helps.
Side note: You can also use the shorter connection string (MongoDB+SRV) and it would still work.

"Login failed" connecting to SQL-Azure from node.js (msnodesql)

I followed the tutorial here for building a node.js website on Azure that connects to a SQL-Azure DB:
http://www.windowsazure.com/en-us/develop/nodejs/tutorials/web-site-with-sql-database/
Here's what my .js code looks like:
var sql = require('msnodesql'),
nconf = require('nconf');
exports.authenticate = function(req, res){
var select = "select userID, clientID from users where username_e = '?' AND pwd_e = '?'";
nconf.env().file({ file: 'config.json' });
var conn = nconf.get("SQL_CONN");
console.log(conn);
sql.query(conn, select, [req.param('username'), req.param('password')], function(err, results) {
if(err)
throw err;
console.log(results);
if(results.length == 0) {
// no match
res.redirect('/login?failed=true');
} else {
// authenticated
res.redirect('/start');
}
});
return;
};
But when I run it on my local node.js, I keep getting
"Login failed for user 'mylogin'"
I copied the ODBC connection string directly from the Azure management
site
I replaced {your password here} with my password
I quadruple-checked the username and password are correct (I can successfully log into the management tools, AND I can connect to the DB fine via SQL Server Management Studio from my local)
I added an IP exception for my public IP address for good measure
I tried editing the connection string here and there (changed username to mylogin instead of mylogin#server, tried using the ADO connection string instead)
I ALSO was able to connect successfully in Java using jdbc. Here's the jdbc connection string that worked:
jdbc:sqlserver://xxxmyserver.database.windows.net:1433;DatabaseName=mydb;user=mylogin#xxxmyserver;password=pwd
And here's the node.js ODBC connection string that does not work:
Driver={SQL Server Native Client 10.0};Server=tcp:xxxmyserver.database.windows.net,1433;Database=[mydb];Uid=mylogin#xxxmyserver;Pwd=pwd;Encrypt=yes;Connection Timeout=30;
I am just completely at a loss here, especially since I can connect fine from my local using SSMS. Anyone else run into the same issue?
In case it matters, I am using node.js v0.8.2 (since that's what's on Azure's VMs) and msnodesql v0.2.1
To anyone else stumbling across this and still getting the problem even after taking out the square brackets, there's a flag you need to set in the Azure management portal to enable other Azure services to connect to your Azure SQL database. To add confusion, when you first create it, it adds your IP address to the list, which is why you seem to be able to connect to it fine from your dev machine but not from your Azure instance.
Anyway, to do this, go into the database's settings in your Azure management portal, go to 'allowed IP addresses' and enable 'Windows Azure Services' under allowed services at the bottom.
Try your query without the quotes around the question mark parameters.
var select = "select userID, clientID from users where username_e = ? AND pwd_e = ?";
Quotes are not needed for string (or any type of) parameters. Parameters are sent out of band rather than substituted directly into the query. This is what makes them so much more secure, since they are never evaluated with the SQL.
The problem was with the Database section of my connection string - the square brackets around the database name were causing the problem. The ODBC connection string Azure tells you to use looks like this:
Driver={SQL Server Native Client 10.0};Server=tcp:xxxmyserver.database.windows.net,1433;Database=[mydb];Uid=mylogin#xxxmyserver;Pwd=pwd;Encrypt=yes;Connection Timeout=30;
When instead you need to use this:
Driver={SQL Server Native Client 10.0};Server=tcp:xxxmyserver.database.windows.net,1433;Database=mydb;Uid=mylogin#xxxmyserver;Pwd=pwd;Encrypt=yes;Connection Timeout=30;
Note the lack in square brackets around the database name.
This looks like it's a bug in Azure's management tool that will hopefully go away soon. Hope this saves someone else several hours of debugging.

Resources