I'm using AWS Cognito for user authentication/authorization and I'm wondering whether I need a User entity/model if Cognito stores all user data? And if the answer is no, what is the proper way to model relations for other entities? Should I use the Cognito ID?
Related
My website uses AWS Amplify and Cognito user pools to authenticate users. When someone submits the registration form on the site, they receive an email confirmation link. Their information is automatically added to the Cognito user pool.
I'd like to add this user's details to our AWS Amplify graphql database and also add them to the "Public" Cognito user group. (I think they must be in this group in order to use features in the website that mutate the graphql database).
I am considering how to add users to the graphql database. One option is to write a lambda function that does this when the user clicks the confirmation link, as described here: https://bobbyhadz.com/blog/aws-cognito-add-user-to-group. Is this the best approach?
An alternative idea is to make our front end call this method of the AWS-amplify library when the user clicks submit on the registration form.
API.graphql(graphqlOperation(createUser, { input: user }))
However, this function is a mutation and therefore requires authorization. Since the user is not yet logged at this registration page, I would need to waive authorization on this function. Is this possible?
I'm building an Angular 11 app with AWS Amplify as the backend which uses Appsync, dynamodb and a managed GraphQL API. I'm using the cognito user pools to authenticate. Authentication works neatly, but I am really confused about how to go about doing role-based authorization. I haven't done this using cognito before but I have a strategy in mind that should theoretically work out. I would like advice on if there is a better way to do this:-
Requirements:-
The app will be used by members of organisations that we are partnering with. Every member will be tied to an organisation. So organisations have their own table and so do members. Members of an organisation can only access content related to their organisation. So right after authentication, the client app has to get the id of the organisation the current user belongs to and also the role they play in that organisation to show/hide UI resources and filter data. Which UI resources they can access depends on the role they play in that organisation and of course the data they see there has to be restricted to what is related to their organisation.
This is a controlled beta release of our application, so Cognito user pools uses email and password to login. No other login option is provided for the sake of keeping things simple. User sign up is not possible. Only admins can add new users for now.
How I plan to do this:-
Cognito API is integrated to the client and the admin will add the
new members from the client UI and the client will add them to the
cognito user pool via the Cognito API
While adding the new members, the admin will specify which
organisation they belong to and what role they play in it. But the
organisation and role are not details that are stored within the
user pools. There is a separate dynamodb table called "members"
which stores these information because these can change frequently
and need to be flexible.
Additions made to the Cognito user pool trigger a lambda function
that automatically syncronizes the "members" table in the amplify
backend in a dynamoDB table with the new additions to the user pool.
So when the admin adds a new user from the client UI, they
fill out a form with the email ID, name, organisation and role of
the new user, and the client UI will create that user with the name
and email ID in the user pool via the cognito API. Once that request
returns the user's ID (remember it will also trigger the creation of
a record in the member's table via the lambda funciton), we create a
mutation to the member's table adding the organisation and the role to the user's record in the member table.
Cognito user pool only has the email ID, name and user ID and
nothing else, all other information is stored in the members table,
which also has the ID, and name (for human reference) but not the
Email ID. We will not be holding the same information in
these two tables to avoid redundancy.
Updates to the email ID can be made by individual users via the
client app which will do it in the cognito user pool via the cognito
API. And no updates need to be made to the member table after email
update since the member table doesn't have the email ID. All other
member details can be made to the members table via the client app.
When the user logs in, as soon as the cognito UI authenticates the
user and sends over the email ID and user id, we fetch the member
details from the member table using the user ID and get details such as their name,
organisation they belong to and their role. And using the
information on their role, we can restrict UI resources using flags
in the UI Code. To achieve this, there will be a separate table that
will let the admin user modify access to the UI resources for each
role. So we'll need to fetch the role and the associated UI tags
right after authentication as well.
And as for how data is filtered as per the organisation, I am not
sure yet, but I would like to use an authorizer that will be
specified using a function in the graphql schema itself, that will
get the organisation ID with each request and use that to filter the
data before returning to the client.
Not sure if this process is solid, but this is what I was able to fathom. Please let me know if I am doing this in a sensible way or if there are better ways to achieve what I am doing.
I am developing the serverless application with AWS Cognito, DynamoDB and Lambda.
I need some user-friendly ids for URL.
Is it possible to generate a number only ids with Cognito User Pool? If not what is the best way to generate it manually in lambda?
Thanks in advance.
No, Cognito only generates UUID format ID, you can get the user ID from JWT, no need put it in the URL.
If you insist on the numbers user ID, you could create a mapping table in the DynamoDB or RDS.
I'm currently setting up AWS Amplify with my react app and adding an API so I can use GraphQL.
I'm currently at a choice to add authorization type and my two options are API key or Amazon cognito user pool.
It's my understanding that the second choice means if a user is signed in, they can interact with the API calls.
What does the first choice (API key) mean?
What is the difference?
API key is basically for unauthenticated workflows where the app doesn't need private access for different users. User Pools allows you to apply fine grained access controls. Take a look at the options with #auth in the GraphQL Transformer: https://aws-amplify.github.io/docs/cli/graphql#auth
API key is for public datas and Cognito user pools for private datas.
A good link :
https://aws.amazon.com/fr/blogs/mobile/graphql-security-appsync-amplify
We are building a number of microservices using API Gateway+lambda+DynamoDB. We need to secure these APIs using Cognito which we are using for user management. We will have a user pool and two groups with a different IAM role attached to each group. The need is users in one group should not be able to access all services and so the users in other group.
Any suggestions, how we can implement this?
The issue is ID token generated by Cognito is not validated by API gateway to check what level of access user has. All it checks is if Cognito ID token is valid or not.
You can use API Gateway custom authorizers to validate policies attached to each group.
From AWS Documentation:
You can use groups in a user pool to control permission with Amazon API Gateway. The groups that a user is a member of are included in the ID token provided by a user pool when a user signs in. You can submit those ID tokens with requests to Amazon API Gateway, use a custom authorizer Lambda function to verify the token, and then inspect which groups a user belongs to.
Additional references to implement:
https://aws.amazon.com/blogs/compute/introducing-custom-authorizers-in-amazon-api-gateway/
https://aws.amazon.com/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/