How to send Dynamodb query results to browser encrypted? - javascript

I have a tiny table (100 records) that I keep in my Dynamodb backend. My web app will scan table at the beginning of the session. And then users will query this data with different parameters. My intention is not to go my backend for each query and do it on client side(front end) for better performance.
But because I don't want anyone to see my tiny table's data I would like to encrypt it while sending and decrypt it on browser side after arrival. I'm using Nodejs, dynamodb and API gateways as backend (AWS serverless architecture).
I'm a newbie and was wondering if it is possible and what the best practices are.
I'll give an example to describe my concern better. Imagine skyscanner keeps all airline-flight-ticketprice data in one table. they will have 2 options to let everbody to search publicly. First they can let users to query the table everytime they search (which will be slow). Second they can scan the table's data and send it to browser and users can search flights much faste on front end (with arrays etc..). I want to implement the 2nd approach but I also want to keep my data encrypted so nobody can copy my data and create a very similar website :)
Thanks.

Using Cognito Identity Pools
You can achieve this with authentication using AWS Cognito Identity Pool(Granting who can access which DynamoDB Table and even which Partition key) and using AWS JavaScript SDK which uses SSL to encrypt the communication between the browser and DynamoDB.
Note: You can also use AWS Cognito UserPools if you don't have a user store which can be connected to Cognito Identity Pool.
Using API Gateway and Lambda endpoint for Temporary Access Credentials
If you already have an existing authentication mechanism you can use a API Gateway and Lambda endpoint where the Lambda function will have the code to assume an IAM Role and send the temporary access credentials to the browser. Then in the browser you can use AWS SDK for JavaScript to access DynamoDB.

Here's a demo app that does specifically what you're looking for...once logged in, the user has access to his own "row" in dynamoDB...
https://github.com/awslabs/aws-cognito-angular-quickstart
Here's what you get by running the install script (it creates all of the resources for you):
http://cognito.budilov.com

Related

Which method is better: Python SDK (server side) or JavaScript SDK (client-side) to add to and update cloud firestore?

I have a Django web application with a postgresql database on an AWS server.
I want to keep this database in sync with a nosql cloud firestore database. We're using cloud firestore as the backend for a mobile app.
This means that every form update or new object that is added to the web app needs to be in sync with cloud firestore.
I'm able to update cloud firestore using the Python SDK when each form is submitted via the web app. However, I want to know if this is the best method to keep these two databases in sync. Each time a form is submitted, I have to import the firebase SDK, and then use the methods to update cloud firestore. Obviously, this will take time, but I'm unsure if this method is better, or if using the JavaScript SDK will be better. In essence, which method will perform better?
When you are doing that from python SDK the read and write to cloud fire storage is done from the server means if you have x request and y number of users doing that, your server has to do x*y request to Cloudflare storage. in this case, your transaction from the server will be heavily based on a user basis but you can use admin SDK in python and give only admin to access to DB.
If you want to use js for the same then request will be shared by users and the server will be free but each user should have access to DB write and read, you have to be more careful about authenticating users.
so if its all read requests and user-based filters are done well use from js, if you have doubts on authentications or you don't want to take a risk in that use from python.

What's the simplest possible way to use DynamoDB from a browser?

I'm building a proof-of-concept UI served as a static JS application (just free static hosting on Netlify), and I'd like to be able to read and write data to a NoSQL database.
As it's a PoC, I need to keep it 100% free. The request rate will be super low; only a few people will ever see it. DynamoDB seems like a good choice for size and cost ($0).
So what's the simplest possible way to read/write data from DynamoDB from a browser client? It's hard to tell what's absolutely necessary. Ideally I'd connect directly to the database (no API gateway, no lambdas), while maintaining some kind of baseline security.
You can query dynamodb from your browser using aws sdk for browser,
you will need to carefully create a IAM user with limited access (eg. no updateTable perms etc. )
Keep in mind that anyone could hijack your access keys and increase the throughput and generate cost ( if they have updateTable priv. ) or query your tables outside of your website and consume all the available capacity.
I would still go with API gateway / lambda
There is no need for API gateway / lambda for simple DynamoDB requests. I would suggest to use AWS Cognito with the AWS Amplify Auth Library to get access to the DynamoDB. Then use a client like Dynamo-Easy which has some nice abstraction, so you can jump start your dev without learning the low level of the DynamoDB JS client from AWS.

Node.js client api key

I have a node.js backend for an ios app that will provide json data to the app. I want to handle client authentication for each app. The users do not need to create an account. I only want to identify the client apps when providing data and save some data for each client on the node server.
How do I handle identifying each app on the server?
If I need to create an API key, how do I handle that?
If there is a way to authenticate the app when the app first accesses the API, how can I create a unique identifier for the app?
Last, what do I need to know before I deploy the node server? Can I get away by just pointing a domain to my router, opening a port and serving the api from there or is it a must to have a web server setup to handle that?
Thank you
You can basically find a lot of blogs posts to get best practices to follow when designing an api. But here is an over all idea
You can create a client key and send it on every api request or add as part of url
Example: api.example.com/v1/users?client=android&version=1.1
Use Middileware. You can either name as to your convenience or have a database to store key value to manage your clients.
Example:
Create a Middleware which does the handling of authentication and API key checker before you forward it to the routes.
android => 0, ios => 1, web => 2
url: api.example.com/v1/users?client=0&version=1.1
There are many ways to create api keys. Here are some of them
UUID - https://www.npmjs.com/package/uuid
Json web token - https://github.com/auth0/node-jsonwebtoken
Oauth - https://github.com/ciaranj/node-oauth
Again, You have a lot of online posts explaining best practices to follow in production. If express.js, You can find best practices to follow here Express Production
This is just an overview. I request you to do a lot of research online and ask a relative more concrete problems you face towards your learning.

Get access to DocumentDB with JS

I'm developing an app, which should connect to an external DocumentDB database (not mine). The app is build with Cordova/Ionic.
I founda JavaScript library from Microsoft Azure in order to ensure a DocumentDB database connection, but it is asking for some weird stuff like collection_rid and tokens.
I've got the following from the guys of the external DocumentDB database:
Endpoint: https://uiuiui.documents.azure.com:443/
Live DocumentDB API ReadOnly Key: P8riQBgFUH...VqFRaRA==
.Net Connection String: AccountEndpoint=https://uiuiui.documents.azure.com:443/;AccountKey=jl23...lk23==;
But how am I supposed to retrieve the collection_rid and token from this information?
Without row-level authorization, DocumentDB is designed to be accessed from a server-side app, not directly from javascript in the browser. When you give it the master token, you get full access which is generally not what you want for your end-user clients. Even the read-only key is usually not what you want to hand out to your clients. The Azure-provided javascript library is designed to be run from node.js as your server-side app.
That said, if you really want to access it from the browser without a proxy app running on a server, you can definitely do so using normal REST calls directly hitting the DocumentDB REST API. I do not think the Azure-provided SDK will run directly in the browser, but with help from Browserify and some manual tweaking (it's open source) you may be able to get it to run.
You can get the collection name from the same folks who provided you the connection string information and use name-based routing to access the collection. I'm not sure exactly what you mean by token but I'm guessing that you are referring to the session token (needed for session-level consistency). Look at the REST API specs if you want to know the details about how that token gets passed back and forth (in HTTP headers) but it's automatically taken care of by the SDKs if you go that route.
Please note that DocumentDB also provides support equivalent to row-level authorization by enabling you to create specific permissions on the desired entities. Once you have such a permission, you can retrieve the corresponding token, which is scoped to be valid for a certain time period. You would need to set up a mid-tier that can fetch these tokens and distribute to your user application. The user application can then use these tokens as bearer-tokens instead of using the master key.
You can find more details at https://msdn.microsoft.com/en-us/library/azure/dn783368.aspx
https://msdn.microsoft.com/en-us/library/azure/7298025b-bcf1-4fc7-9b54-6e7ca8c64f49

Secure access to 3rd party API from a Javascript app

I am creating a web app in Angularjs which displays data from a 3rd party API (json). This is not a free API, I have to pay based on the amount of calls made.
I am given an API key which I call like this:
https://apiservice.com?key=1234567&p1=x&p2=y
I want to ensure that my api key is used only by my web app, so I created a proxy on my server. Now my angular app calls my server like this:
https://myserver.com/myapiproxy/?p1=x&p2=y , the server makes the call to the api using the key that is kept on the server, and returns the json data to the client. This way the key is kept secret.
However there is currently nothing to stop somebody else from calling "myapiproxy" and get the data.
Is there a way to ensure that only my app gets the data and that others can not make calls to the api on my expense?
I searched for a few hours and I couldn't find a truly secure answer. HTTP referer is not a good answer because it can be easily spoofed.
Take a look at JSON Web Tokens - https://jwt.io/
It is a good way to secure your calls. It has angular module - https://github.com/auth0/angular-jwt
When user loads your app you can provide a token jenerate on the backend and store it in local storage.
Than on each api call you can check if this token is authentic.

Categories

Resources