Best way to connect to remote, server-side database with Expo?

Hi! I’m new to Expo and JavaScript. I’m trying to figure out the best way for my app to connect to a remote RDS database hosted by AWS. I have a Postgres database (although I could change it to SQLite or any other provider) and I want my app to access and edit this database as users use it (i.e. to load info for each user, record posts from a user, etc). I found pg is a library that allows you to connect to remote Postgres databases in JavaScript, but it does not seem to work with Expo because it uses Node Standard Library APIs. Is there a library to perform this task recommended by Expo? I know of the SQLite library but this seems to only be for using client side databases whereas I’d like to be able for my app to connect to a database on my server.

Any help would be greatly appreciated!

My SDK Version is 37.0.1 and I’m building my app for IOS and Android.

Hi

Connecting to a database directly from an Expo app (or e.g. JavaScript running in a browser) is not secure. If you do that any hacker would easily gain full access to your database.

For this reason you will need a server between your app and the database that controls the access and makes sure the user of the app is authenticated and that the app only makes allowed and sensible queries. There are basically an infinite number of ways to write this server code. e.g. it could be an app written in PHP or Ruby on Rails or Django or Flask or one of many Java frameworks or JavaScript (running on node) etc. If it’s written in JavaScript you’d be able to use the pg library you found.

So then the mobile app makes HTTP requests to the server. The server makes sure the requests are from valid users and that the user has the relevant permissions to e.g. delete the records they want to delete or whatever and then makes the request to the database on the user’s behalf. It will then return the results to the app (e.g. as some JSON data). When the app receives the response from the server it can update the UI as appropriate or notify the user that there was an error or whatever.

I hope this gives you an idea of what is needed.

1 Like

Thank you! That makes a lot of sense. One follow up question: what is the standard way for the server to make sure that the requests are from a valid user? Would I send a user’s username and password in the HTTP request to the server and it checks it against a database before proceeding with the request? Should this only be done with HTTPS? Or would sending the username and password in any form just be a bad idea?

Thanks so much for the helpful answer!

1 Like

There are a couple of ways to do this. Yes, one way is to POST the user’s username and password to the server. And you’re right that this should be done over HTTPS. The server should validate the username and password (Careful. Don’t store the passwords in the database as plain text. Otherwise if someone manages to hack your server they will have access to the users’ passwords that they have probably reused for Gmail etc. so the hacker might be able to use them to gain access to other accounts belonging to the user. Also, don’t just run them through MD5 either, because although that’s much better than storing them in the clear, it’s still often possible to get the original password back e.g. using a reverse hash lookup or via brute forcing the hash. You need to “salt” the password hashes. Basically you should not implement this from scratch yourself unless you know what you’re doing. You should use whatever your framework provides for authenticating users. e.g. Rails has Devise and Omniauth for this sort of thing.)

After the server knows that the user has provided a valid username and password it would normally do something like storing the user’s user_id in the user’s session. Then in the response to the browser or mobile app it would send back a cookie with the user’s session_id. Then in subsequent requests, the browser or mobile app would send the cookie to the server instead of sending the username and password with every request.

The other way to do the authentication, which I am less familiar with, is basically for the user to authenticate against another service like Google, Facebook, Twitter, GitHub, etc. and then get a token back which your app sends to your server to say “Google says I’m such and such a user”. In your database you’d e.g. store a mapping of someuser@gmail.com is user_id X. If you do it this way you don’t need to store the usernames/passwords in your database, so even if your server gets hacked, there are no passwords to steal. There are a few different protocols for doing this sort of thing. The most common these days seems to be OAuth2 + OpenID Connect. In your app you’d use something like this guide. On the server it would depend on what language and framework you’re using. I have never implemented this myself, on the client or the server, so I’m not sure I’ll be much help if you decide to go this route.

The username/password option is definitely easier to implement.

1 Like

Thank you so much! This is so helpful to get me started.

See also the documentation on the OWASP site. e.g.:

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.