Confused on use/ need of cognito - amazon-web-services

So since parse is shutting down we are moving our website / mobile app that we've been developing to AWS. We are primarily going to use the following services:
SNS, SES, Dynamo, S3, Lambda.
Now I am still a bit confused on:
what cognito is used for? Do we really need cognito to authenticate users and use DynamoDB, S3, SNS ? Or can we just use specific APIs for each of these services and connect directly (using Js SDK)?
If we do have to use cognito how do we save local data i.e logged in user/ identity? is that what cognito sync is for or do we have to use cookies ?
In summary why do I need cognito when I can directly connect to DynamoDB using the JavaScript SDK?!
Thank you in Advance.

Amazon Cognito can be decomposed in two sub-services: Amazon Cognito Identity and Amazon Cognito Sync.
Think of the former as an authentication service and a credentials provider. The latter is just a service to store user data and keep it synchronized between multiple devices.
What is the purpose of Amazon Cognito Identity?
Suppose that you have a table in DynamoDB. Let's say that you have a web application that will store an item on that table.
You can create an user in IAM, embed the credential information on the web application, and then put the item on the table using the AWS SDK.
There are three things going on here:
The credentials are embedded in the application
The credentials do not expire.
Every user in your application has the same access rights on your table
This may be fine for some applications, but Amazon Cognito Identity offers a solution to these common problems.
Let me explain Cognito Identity's workflow:
An user registers an account on your application, sending all the information (username, password, other data...) to your server.
The server stores the user in some back-end database (it could be a DynamoDB table) and creates a new identity on the Cognito service. This identity is then mapped to this user.
The user can now login into your application. The user logins and sends username and password to your server. (This process could be done automatically after account registration)
The server checks the username and password against your back-end database. If everything is right, then the server makes a request to Amazon Cognito for a temporary access token.
The web application receives the token and makes a request to Amazon Cognito (using that access token) to get the user credentials. These credentials are basically a temporary IAM user that was created specifically for this user. It will have an expiration (usually an hour).
The web application uses these credentials to make operations on AWS, such as putting an item on a DynamoDB table, or calling a Lambda.
When the credentials expire, the user must re-login into the application. This might be done automatically or not, depending on your application's requirements.
On the Amazon Cognito dashboard, you can configure roles and policies for your "identities" (an user in Cognito). This way you can specify which services it can access. It even allows you to create access roles for your users (Admin users may be able to access some services that normal users should not).
I should also note that Amazon Cognito can be easily adapted to support Facebook / Google+ / Amazon accounts, which will be mapped to the same identity, so the user can login via multiple sources.
What is the purpose of Amazon Cognito Sync?
Consider it like a DynamoDB table where you store information for a specific user. These information is shared between multiple devices and is always synchronized. This means that when a web application updates an user value, then the mobile application will automatically reflect this change.
There is a limit on how much user data you can store (I don't remember now), so it's not something you would use to persist information (such as an user password), but rather a mean to share information.

Related

AWS cognito authorization

I have an application (node.js) that need an Authentication and authorization.
My app need access to postgres database and also need a Inheritances (roles etc.)
One option to implement that is using the cognito service of aws (the app will host on aws properly - not sure about that)
so the questions is
Is cognito service support the authorization for node.js with database that is not services on aws? (I read that "identity pool" is for aws services like mariaDB)
If my app will be on heroku (not on aws), I will also be able to use with cognito services (for authorization)?
Is cognito support roles/users inheritances ?
Tnx
Cognito identity pool is used for granting access to aws services. User pool is used to exchange user credentials for tokens which can contain additional information about the user once decoded. So yes, you can use user pool just for authentication. Your user attributes can contain information related to the services this user needs to access.
However, if you plan on storing database credentials, I suggest you use AWS secrets manager to store your DB credentials and grant the cognito user access to this secret. You'll need to use both user pool and identity pool in this case.
Not directly, but you can use it to access secrets manager where you db credentials are stored.
Yes you can use cognito anywhere. It will be connecting to AWS to grant you tokens however. And these tokens are only recognized on AWS. Which is why you need to use them to access other secrets that can be used to access whatever other services you want.
Cognito supports groups. I'm not sure if that's what you mean by inheritences. You can have token based roles with groups.

Suggestion: Integrating Amazon Cognito with AWS DynamoDB

I've built an application which is connected with Amazon Cognito to take the sign in and sign-ups of users. Currently, application support three different subscriptions (Free, Basic, Premium). If the user signs in for basic Subscriptions, I want to give them least access to DynamoDB for download the parts of applications which is required to run the application service.
How to connect DynamoDB with Cognito directly
I am not sure, what's the best approach to follow this scenario?
(Please note- this is not a mobile-based application, so do not give suggestion to use AWS Amplify or relatable services)
When I was first learning about Cognito, I had made the same set of assumptions you are currently making. I knew that User Pools could act as my application's user directory, and Identity Pools would magically unlock all my authorization needs. I was mistaken :)
At the risk of oversimplifying, AWS Cognito exists to answer two questions:
Who are you? (authentication)
What can you do? (authorization)
Cognito addresses these concerns with two distinct offerings: User Pools (authentication) and Identity Pools (authorization).
At a high level, User Pools let you handle user registration, authentication, account recovery, and supports authentication with third-party identity providers like Facebook, Google, etc. Sounds like you might have this part figured out.
Cognito Identity Pools, on the other hand, provides a way to authorize users to use various AWS services. You can think of it as a vending machine for handing out AWS credentials. For example, if you needed to give your users access to upload a file to an S3 bucket or to invoke an endpoint in API Gateway, you could do so with an Identity Pool. You can even allow item-level access to DynamoDB based on an Amazon Cognito ID. However, this might not work the way you expect since your application users are probably not directly connecting to DynamoDB.
In most web/mobile applications, users are not connecting directly to DynamoDB. Instead, they are interacting with a web/mobile app that communicates to the back-end of your application via an API. That API would then communicate with DynamoDB. If your stack is in AWS, the path may look something like this:
Client (web/mobile app) <-> API Gateway <-> Lambda <-> DynamoDB
In this architecture, your users would authenticate via Cognito. Cognito would then authorize the user to make calls to API Gateway. API Gateway would execute your lambda, which would then interact with DynamoDB. The "user" of DynamoDB in this example is your Lambda, not the user of your application.
That last bit is important, so I'll repeat it: Unless your users are directly connecting to DynamoDB (not recommended), they are not the "user" operating on DynamoDb. Therefore, restricting DynamoDB access based on a user's Cognito ID is not going to be an option for you.
So, what can you do? Your application needs to provide the business logic around what effect your users can have on DynamoDB. Perhaps free users have read-only access to a specific partition, while premium users can modify the same partition. That logic has to be handled directly by you.
I know you said you weren't looking for Amplify suggestions since your application is not mobile-based. However, Amplify offers SDKs that aren't specific to mobile development. The folks at Serverless have made a fantastic tutorial on building a full-stack serverless web app, which includes a very readable chapter on serverless auth with Cognito. They use Amplify in a web app to integrate with Cognito, S3, and API Gateway. If that's something you are trying to do, I'd recommend checking it out.

How a mobile app should authenticate to AWS

I'm developing a mobile app that must access some AWS resources, so it needs authentication to AWS endpoint. The app doesn't manage users (sign-in, sign-out, register and so on).
My first solution was to create a IAM user dedicated to the mobile app and embed its credentials in the mobile app code. The app authenticate itself to AWS using the embedded credentials. It works, however AWS suggests to avoid embedding credentials directly in the app.
I think a better solution is Cognito. Because I don't need users management, I should use unauthenticated (guest) identity to request temporary AWS credentials.
However I don't understand why a guest Cognito identity is more secure than an embedded credentials. The mobile app receive a temporary AWS credentials by sending a Cognito Identity Pool ID, that is a long-term "number" embedded in the mobile app. If someone is able to find this Identity Pool ID, she can receive AWS credentials and access AWS resources as my official mobile app. It seems there's no difference between embedded AWS long-term credentials and huest Cognito access.
Why Cognito solution is better than embedded AWS credentials?
If you are creating unauthenticated access using identity pool, you are allowing public to access your AWS resources. Make sure you write your policy carefully and it won't matter if you use a single IAM user or cognito unauthenticated access as far as security is concerned.
Using federated identity will provide you benefits like getting statistics on usage and adding triggers to events. Also keep in mind that creating a single IAM user and then allowing multiple people to use these credentials is a "hack" way of doing what cognito federated unauthenticated idenity was designed to do. You might run into unexpected complications later if AWS decides to throttle this behavior of IAM.

AWS Cognito: Do I need other AWS service to write a full functioning signup/signin system?

I am planning to write a mobile app with AWS handling the backend work. Like many common apps, mine will support user registration and login. All backend resources should be secure based on the user's role.
After reading AWS Cognito, it handles both Open authentication provider and Developer Authentication provider. This helps to support third party login. The capacity of syncing data is a big plus.
However, I have some questions about Cognito when I try further implementation.
What are the user credentials stored?
I need to add more user attributes (eg. email, profile image etc.) when a new user is created. Can Cognito handle this? Or do I need to use storage like S3 to store the entire user profile?
Does Cognito support email verification for user registration?
Does Cognito handle 'forgot password' feature?
All advices are welcomed.
There is now Amazon Cognito User Pools (currently in beta), allowing to store user credentials, see here
Update: Cognito has since added a new feature that does allow storing credentials. See Cognito User Pools for more information.
Amazon Cognito does not store credentials. Instead, it allows you to offload the task of securely storing credentials to any OpenID Connect-complaint credential provider such as, but not limited to, Facebook, Google, and Login With Amazon.
If you have a credential provider that is not OpenID Connect compliant, you can use the Developer Authenticated Identities capability to leverage another authentication system as a credential store (such as your own back-end service). Registration, email verification, and forgot password features would be handled by the Identity Provider: Either an OpenID Connect provider (e.g. Facebook) or your own provider via Developer Authenticated Identities.
Cognito's Sync capability gives you the ability to store profile information or any other information specific to the current user (referred to as "identity" in Cognito). There is a good blog post about using Cognito Sync to store & synchronize data here.

sendMessage to SQS from Browser

I am building an SPA with Django REST as the backend. Right now I am using the standard Django authentication system and User models.
I would like the JS running on the SPA to be able to insert messages into an AWS SQS (i.e. sendMessage).
AWS has these doc on calling sendMessage from JS in the browser.
They also provide these docs on how to authenticate the user. My thought right now is to use Amazon Cognito. From the FAQ:
Q: What if I register and authenticate my own users?
Amazon Cognito can integrate with your existing identity system. With
a simple API call you can retrieve a Cognito ID for your end users
based on your own unique identifier for your users. Once you have
retrieved the Cognito ID and OpenID Token Cognito provides, you can
use the Cognito client SDK to access AWS resources and synchronize
user data.
Am I correct that for this to work, I would need to:
Create an IAM user for each user in my system. Or do I just need one IAM role?
When the user logins in my site (Django backend), I would have my backend then make "a simple API call [to] retrieve a Cognito ID"
Send that Cognito ID when the user loads the SPA.
User the Cognito ID from the JS running in the browser to call sendMessage to the SQS queue
Am I missing something here? Is there someway to remove the Django User backend and just user IAM Users so that I can avoid having to keep the two users lists in sync? I found this project but it does not seem to be maintained.
UPDATE:
It seems that there might be an alternative method of doing this where I don't use Cognito at all but rather expose an endpoint that can sign requests, "Query Request Authentication". This Heroku page talks a little about building a signing service.
Is this in fact an alternative option and if so what are the pro/cons of these approaches?
Amazon Cognito does not require you to register IAM users, just the 2 IAM roles. A slight modification to what you would need to do:
Create an Amazon Cognito Identity pool, configure with your developer provider.
Update the IAM roles associated with your pool to allow access to the services you want (for instance SQS).
From your Django backend, call GetOpenIdTokenForDeveloperIdentity to get the OpenId Connect token and identity Id for this user, return this to your JS application.
Configure your CognitoCredentials in the JS SDK. In the logins map, use the key cognito-identity.amazonaws.com and the value as the token returned from your Django backend.
Use the JS SDK to call SQS or any other services you wish from your application.
While using pre-signed URLs for SQS can work, using Cognito with the JS SDK will allow you to leverage other services supported by the SDK (DynamoDB, SNS, S3, etc).