Store user attributes in Cognito or AppSync? - amazon-web-services

I'm using AWS Amplify and I'm wondering is it best to store user attributes as custom Cognito attributes or in a user table for AppSync?
Cognito approach:
'username': 'jdoe',
'password': 'mysecurepassword#123',
'attributes': {
'email': 'me#domain.com',
'phone_number': '+12135555555',
'custom:favorite_flavor': 'Cookie Dough' // custom attribute, not standard
}
Pros: Single source of truth
Cons: Not part of the API
AppSync approach:
type User
#model
#auth(
rules: [
{allow: owner, ownerField: "owner", operations: [create, update, delete, read]},
])
{
id: ID!
owner: String
favoriteFlavor: String
}
Pros: All the capabilities of the API
Cons: Each person has two "users" (a Cognito user and a table user)
If the AppSync approach is best, should other fields carry over to the table (like the name or email)?
Thanks!

From my experience, use both is the best.
Fields related with authenticated (email, username, phone, ...), save it on both Cognito and DB. 1 Cognito custom attribute "custom:id" to mapping with User "id" in DB.
Other attributes, save them to DB for more flexible. Because cognito Custom attributes can't be searched, and the Cognito APIs Limit (request per second) is not good for using regularly: https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html, so save and fetch from DB is better.
When user update fields related authenticated, you have to update on both Cognito and DB.
Hope this help you.

Related

Cognito make username an email google auth

How do I make my cognito user pool username an email with google identity provider.
It is very confusing as well. In attribute mappings it says that google sub is username, but username has a format of "Google_randomnumber"
Please help me how do I assign my own username when doing google auth with cognito user pools?
I think if you want the real name, you need to join given name and family name. The user name, you need to add an attribute it's Google username.
This is what looks like when you click the User in Users and Groups:

Django Authentication credentials separate from user data

I am building a system where many accounts will not have login credentials (e.g companies) unless specifically provided. In order to achieve this, I have the following account model (not implemented yet, currently designing on a piece of paper):
Table: Account
Fields: ID, fname, lname, type, created_at, activated_at
Table: AccountCredentials
Fields: Account ID, email, password
Relations:
Account <- 1-to-1 -> AccountCredentials
All permissions, operations etc will be performed over the Account model; so, the Account model will be the django auth user model.
I have used custom User models and managers before; however, this is something I am not sure how to implement.
How should I tell the AbstractBaseUser model to authenticate using credentials.email and credentials.password (credentials being the relation name between Account and AccountCredentials)? From checking AbstractBaseUser source code and checking some files, it seems like I can override get_username method; so that, the username field is being read from credentials. However, I am not sure how to do the same for password as it is hard coded in model.

Django REST auth - users stored in external service

I've been wondering the best way to handle the case where a Django is used in a service-oriented architecture, so individual Django applications do not maintain their own user stores. One service maintains the user store, and others must call it in order to retrieve user information.
So far example, here is how I was thinking of building a custom authentication class in Django REST to handle this:
class SOAAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
token = request.get_token_from_auth_header()
if not remote_auth_service.is_token_valid(token):
raise AuthFailed('Token is invalid')
user_properties = remote_users_service.get_user(token):
# user_properties is a dict of properties
if not user_properties:
raise AuthFailed('User does not exist.')
user = MyCustomUserClass(**user_properties)
return (user, 'soa')
So no user info would get persisted in the Django application's database, and permission classes could interrogate the instance of MyCustomUserClass to figure out what groups a user belongs to.
Would this approach work for simple group-based authorization? My think is that I don't need object-level permissions, so there's no need to create rows for my users in the Django database.

Normal user/token user authentication

In my Django project I need two type of users:
- users authenticated with login/password (django.contrib.auth.models.User)
- users authenticated with token (Django REST Framework)
What's more I wish I could keep both of them in one table and display only "User" page in admin panel.
What would you suggest will be the best solution?
The token from DRF doesn't create a new User table it just creates a Token table with a one-to-one relationship with the existing User table, so you'll always have a single table (admin page) "User"
You decide what users should have a Token. for example:
# create API Token
regular_user = User.objects.create_user(....)
api_user = User.objects.create_user(...)
Token.objects.create(user=api_user)
now regular_user can only access using login/password (since he doesn't have a Token) and api_user can do both
Hope this helps

Django Integrating Python Social Auth And The Default Auth With A Custom User Model:

I have a project I am working on that requires some users to be authenticated via facebook and others to sign up using a custom model. The facebook users will not have the same sign up credentials as the custom model. For example- there will be a restaurant owner sign up and a customer signup. The customer will not have to put a street address location, they can simply login.
My intentions were to have the restaurant owners sign up via the custom profile model and the facebook users to simply login via the defualt social auth, but whenever I combine the two, social auth starts to use the custom model because I define a custom user model within settings. Is there a way to distinguish to the python social auth backend to only use the default or a way to update my current custom user model to have a facebook segment. I have searched the web for a long time for this, but can not seem to find anything that can combine the two besides (1), but it did not work successfully. I can however get one or the other working successfully depending on if I specify a user model in my settings.py file or not.
It is quite simple, but I do not know of a way to get social auth to look at its default and djangos authentication to look at my custom model.
(1)-http://code.techandstartup.com/django/profiles/
In order to distinguish one type of user from another, you can do something like this:
First, in your settings file, store the following:
FIELDS_STORED_IN_SESSION = ['type']
This will be stored in strategy parameter in every function of pipeline
Then, change the pipeline wherever necessary. For example, in your create_user pipeline function, you can do this:
user_type = strategy.session_get('type')
if user_type != 'customuser':
return {
'is_new': True,
'user': strategy.create_user(**fields)
}
else:
return {
'is_new': True,
'user': create_restaurant(**fields)
}