Using Firebase & Amazon S3 with correct security setup - angularjs

We are developing a web application based on Angular JS on front end and firebase in the backend. We are considering to use Amazon S3 service to store the images and other attachments. The users logged in on our application are allowed to upload. Only some uploads are readable by public.
As there is no server side execution with firebase, what is the correct procedure to do such a setup without statically exposing the credentials publicly on the front end?
If is it not possible, we are considering to run a node.js server which is generating the credentials dynamically and writing into firebase. The frontend can read and use this credentials to upload the document to S3 bucket. But this is our last option.

Related

What are the best ways to store user info for your Flask app?

I am creating a SaaS app with a user + password. After authentication, the user can access some semi-public services, but also encrypt some files that only the user can access.
I am building the front end of my app with HTML CSS JS & backend with Flask
struggling because there are so many people saying if you store personal info in your own database you will get in trouble
should I just store them in my database or are there any third-party services that can help with it
*is it legal and safe to store user info in your database?

what credentials to use for deployment of react app on aws

I have created an app that uses amplify for deployment, and dynamodb for fetching data, I am using the credentials provided to me, but for deployment, should there be separate user credential which should solely be used for deployment?
I have API_ACCESS_KEY in aws-export.js (which I have added in .gitignore), so which credentials should be there in aws-exports.js, specific deployment credentials which could be accessed by anyone, or my user-credential which are actually specific to services alloted to me as a user in the org (which I think is not correct way of managing access)
What is the best practice for this?
There's no such thing as a cookie cutter way to provide credential so that CI/CD servers could get authorized to deploy, you will have to pick one that's right for your use-case. This would usually revolve around the question "Where is the CI/CD server located?". or "Where is the deployment gonna originate?"
If its inside AWS, you can assign IAM roles to authorize that server to push / sync react build files to S3 and invalidate files in CloudFront. If the CI/CD server is living outside of AWS, you will have to generate AWS credentials that only posses enough permissions to sync data to S3 and invalidate cache in CloudFront.
You can then place the AWS credentials in either Environment Variables or create named profiles.

Firebase for real time feature while keeping my own rest service and backend database?

I have angular JS application that gets data from REST service with sql server backend. I develop and have control on all 3 parts - angular app, rest service and database.
I want to now add pizazz by making this app near real time by using Firebase. My question is - can I keep my current rest service and database for the most part and only use Firebase database and the library minimally and only where necessary to support real time?
You can do this using JSON Web Tokens (JWTs). This is possible because as you mention in your question, you control the REST service and the SQL server. Thus, because the server is trusted you can connect it to your Firebase database by authenticating it using a JWT.
As a result you can keep managing user accounts the way you currently do with the added "pizzaz" of making a subset of data available in "near real time". Firebase app JWTs can be generated with any existing JWT generation library and then signed by a SHA-256 HMAC signature.
Authenticating Servers
Because you are running a trusted server that is connecting your own Firebase database, you can authenticate it in several ways:
Using a Firebase app secret: All authentication methods can accept a Firebase app secret instead of a JWT token. This will grant the
server complete read and write access to the entire Firebase database.
This access will never expire unless it is revoked via the App
Dashboard.
Using a secure JWT with the optional admin claim set to true: This method will grant a server complete read and write access to the
entire Firebase database. This token will expire normally, so it is
important to set the expiration times accordingly.
Using a secure JWT designed to give access to only the pieces of data a server needs to touch: This method is more complicated, but it
is the safest way to authenticate a server as it lets the Security and
Firebase Rules prevent the server from doing anything it's not
supposed to, even if it becomes compromised in some way.
Source: Firebase Documentation -
https://www.firebase.com/docs/web/guide/login/custom.html
Generating Tokens
There are Helper Libraries available for many platforms but for this example I will use the Firebase Token Generator for Node.js made available by Firebase.
Firebase Token Generator for Node.js:
https://github.com/firebase/firebase-token-generator-node
Step 1:
Install the package using either npm or Bower (or compile from source).
Step 2: Copy the app secret from your Firebase instance's dashboard.
Step 3: Generate a token using Node.js by passing your Firebase app secret to the FirebaseTokenGenerator constructor method like this:
var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator("<YOUR_FIREBASE_SECRET>");
var token = tokenGenerator.createToken({uid: "1", some: "arbitrary", data: "here"});

Secure way to download AWS S3 Contents from mobile app

Problem Statement:
I want to download S3 contents through mobile app from multiple mobile devices.
Solution that I came across.
Solution 1
Create an IAM user in AWS. Create a policy to download S3 contents only for particular bucket and assign that policy to IAM user.
Whenever mobile application wants to download contents from S3, mobile application will call my server API which will return the credentials of IAM user.
Then mobile application will use these credentials to download the S3 contents.
Solution 2
Use AWS Cognito service.
However the problem with first approach is that I will have to manage credentials server side. Also someone can easily back track it and use those credentials outside application to download contents.
The second approach I am not aware of completely. However in the FAQ of AWS COGNITO service I did not found any solution to my requirement although it allows you to read, delete and put the content to any AWS service.
I need a suggestion regarding securely download S3 contents from mobile applications.
Amazon Cognito and the AWS Mobile SDK are designed especially for the use case of downloading content stored in S3 from a mobile app. You can use Cognito to provide temporary, limited-privilege AWS credentials to each user of your app. You can enable your users to start using your app as unauthenticated guests and/or authenticate with social logins or your own registration/login service.
To set up Cognito, use the Cognito console to create an Identity Pool, which is a store of user identity data specific to your AWS account. IAM roles define the permissions for your users to access AWS resources, like S3. Users of your application will assume the roles you create. You can specify different roles for authenticated and unauthenticated users. To learn more about IAM roles in Cognito, see IAM Roles.
When you visit the Cognito Console, a wizard will guide you through creating the Identity Pool and the necessary IAM roles. The integration between Cognito (which issues AWS Credentials to the mobile app user) and the other AWS Services is in the initialization of the SDK. Example code for initializing the SDK with Cognito on iOS, Android, Unity, and JavaScript are in the Getting Credentials topic of the Amazon Cognito Developer Guide].
Updates in October 2020:
AWS has shifted their "Mobile SDK" to AWS Amplify. Amplify still uses Cognito for authentication (login) and authorization (credentials/permissions) so the above is still accurate. You can get specific guidance on using Cognito with Amplify to set up Authentication here. Once you set up auth in Amplify, a specific example of using S3 is here.
Note that Cognito's docs focus on User Pools these days which allow you to implement your own full-fledged directory for storing and logging in users (for a cost). However, you don't have to use Cognito's user directory to store your users. Cognito Identity Pools (which still have no cost AFAICT) allow you to get AWS Credentials for users who are not logged into your app (so-called "Unauthenticated Identities") and/or allow users to login with other user directories (such as social logins or a user directory that you own and manage).
If you want ultimately flexibility, you can also use AWS STS to get credentials for accessing AWS Resources including S3. However, with STS's flexibility comes the need for more understanding of IAM/AWS and arguably more complex setup.
Please comment if there is anything I can do to make this more clear!

How should I authenticate my SPA frontend with my API since I´ve got no authentication process in the site?

We are designing a web site for selling financial products online.
The following is a high level description of the components:
Our frontend will be a SPA built with AngularJs.
The frontend will communicate with an API hosted in Heroku.
The API will expose web resources which allows the execution of the
business process.
The API hosted in Heroku serve as a passthrough between the frontend
and the real services which actually do the tasks.
The purchase process is designen to not ask for user/password or
account creation at any point.
We have some queries we execute thru the API which returns confidential information -confidential according to the local law-
We want the frontend to authenticate to the API to retrieve this information still NOT asking for credentials to the user.
We thought about a local persistence of the credentials and obfuscating the request but that would be easy to break with a proxy so the request can be read clearly.
What would be an option for this need of authenticating the frontend without asking for credentials to our clients?

Resources