I really hate coming to stackoverflow with such a noob question but my searching has returned little to nothing useful.
So, I've implemented Amplify and Cognito for authentication, that all works but I obviously need to store some additional user information in a database. In my case, I'm going to be using DynamoDB.
My question is, how? How do I reference a user in the database from Cognito? or more specifically, how "should" this be done properly? I can think of a thousand ways to do it, but being fairly new to this side of AWS, I'm not sure of the best path to take.
I'm sure I'll get hammered on this question (always do) but thanks for any genuine advice for somebody with a basic question about how to properly implement something.
Each Cognito UserPool user has a unique UUID UserID. It is the natural choice for the DynamoDB Partition Key for user records. Cognito can trigger a lambda on certain events like sign-up, giving you the opportunity to bootstrap the new user DynamoDB record.
Depending on your use case, Cognito user pool attributes may be an alternative DynamoDb user records. You can set (immutable) string and number values on custom attributes for each user.
Related
Similar questions (eg. this) have already been asked and answered in negative. I'd like to if any alternatives exist.
I am developing an application where users can collaboratively edit a document. I don't want to force every user to login. I would like to allow users with a link to be able to edit a document (similar to what Google Docs allows). I was planning to share a token in the link which when presented would grant write access. I would have stored the tokens in a separate collection and matched them. But as per previous answers this is not possible and a security issue.
I don't consider it a security concern (for my purposes). The token is like a pre-shared key. Whoever presents the key is allowed access. If the owner thinks that the key is compromised, he can revoke the same. Kindly help me with a way to achieve this. I'm also curious to know how other apps like Google docs achieve this.
As Mentioned by #Dharmaraj,
In Firebase security rules, you have 3 pieces of information, namely the path, the data and the token. Except from those three you can't pass additional information in a security rule.
Cloud Functions would be a better fit here, given the flexibility. Additionally, with Cloud Functions you'd not be forced to authenticate users, and still be able to connect to Firestore if needed.
I'm new to react native. I am trying to develop an application that uses firebase user authentication. But there is something I can think of. For example, 2 users have registered to my application but I want to show extra information to the first user according to a condition.
How can I separate these two?
Where exactly should I manage this condition?
The question is not super clear as to what issue you are trying to tackle so I apologize if I am inferring incorrectly.
I use MongoDB personally with a Node/Express backend for user data and haven't used Firebase myself but I'm sure you can do the same things with it. I'll be speaking in Mongo terminology but again I'm sure you can do the same with Firebase and at the least this will give a good idea of the thought process.
I have a UserSchema that holds all the user information. When logged in the client app would get this information to be used on the frontend after authentication.
Assuming you are only displaying "extra" information that doesn't need additional privilege you can just pull in the users data stored in firebase and handle the display of this extra info with logic on your frontend client.
If its extra privilege you need to setup firebase to look at the user data that is authenticating and only serve back information if they have the proper privileges.
Also important to note, you should ensure that when you are updating user information from client -> firebase backend you should ensure that you can only update specific user fields via read/write authentication on firebase.
Hope this gives a little better idea on how this process might look. I'll let someone who has used firebase specifically add tech specifics.
Firebase is great as it offers a lot of authentication providers. In one of my apps, I use four different providers provided by Firebase (Email, Twitter, Facebook and Google), but I also need to let users sign in via LinkedIn.
As Firebase SDK does not offer LinkedIn, I need to implement the login flow manually, which doesn't seem to be difficult, but there is one huge issue which I see. During the creation of a custom JWT token, I need to assign a user ID. And I have no idea how to generate one while making sure that my approach will not conflict with user IDs which Firebase generate on its own for other providers.
For example, let's imagine that a user Andriy Gordiychuk signs in via LinkedIn and his email address is andriy#gordiychuk.com. A simple way to create a user ID would be to take an email address (andriy#gordiychuk.com) and to randomise it using some hashing function. I would get some random id such as aN59nlphs... which I would be able to recreate as long as the same user signs in. So far, so good.
However, how can I be sure that the ID which I get is not already used by another user who signed in via Twitter, for example?
One way to mitigate this issue is to store LinkedIn user IDs in a Firestore collection. Then, when I need to create a token, I first check whether I already have an ID for this user. If not, I would hash the email address, and I would try to create a user with this ID. If this ID is already occupied, I would then try to create another ID until I stumble upon an ID which is not occupied, and I would then use it.
I don't like this approach for two reasons:
Although the chance that I would generate an already occupied ID
is small, theoretically the process of finding an "available ID" can
take a lot of steps (an infinite loop in a worst-case scenario).
Once I find an available ID, I must store it. Given that all these calls are asynchronous there is a real chance that I would create a user with a suitable ID, but because the save operation fails, I would not be able to use this ID.
So, does anyone know how to choose user IDs for such use case correctly?
It's fairly common to generate a string with enough entropy (randomness) to statistically guarantee it will never be duplicated. This is for example behind the UUID generators that exist in many platforms, and similarly behind Firebase Realtime Database's push keys, and Cloud Firestore's add() keys. If there's one in your platform, I recommend starting with that.
Also see:
The 2^120 Ways to Ensure Unique Identifiers, which explains how Firebase Realtime Database's push() works.
Universally unique identifier, Version 4 on Wikipedia
the uuid npm module
I'm new to meteor and I've reading a lot however I'm a little confused around the meteor.users collection and the best way to use it. My interpretation of the best practice guide is that meteor.users collection should only be used for managing the accounts.ui package; email, password and username. The guide states that profile is insecure, a flaw in the original meteor design and should not be used.
So my question is, if I want to create a user profile that contains things like first name, last name, age, address, avatar etc do I create a separate collection like 'userProfile' and link it using the meteor.userid or am I suppose to keep it in the meteor.users collection somehow
Common practice is to put user profile information such as the kind you're describing into Meteor.user().profile. In fact people often do much more, for example memberships in groups, arrays of postIds, all kinds of things. Keeping a separate 1:1 profile collection is an option but there's no fundamental reason to do so that I can think of. On the contrary it makes things just a bit more complicated.
Update: As #jonatan points out in the comments, the Meteor Guide has now unrecommended the use of the profile field in the user document.
Instead they recommend storing custom user information as top-level keys in the user document. This is not only more secure but also more performant since incremental updates can get published over DDP on top-level keys but on sub-keys.
Meteor.user().profile is always auto-published for the current user even after the autopublish package has been removed. Information about other users is not published at all unless you explicitly setup a publication. In that case care must be taken to only publish those fields that should be visible to other users. For example you may only want to publish the usernames of other users and not their email addresses for privacy. You would do this with:
Meteor.publish('otherUsers',function(){
return Meteor.users.find({},{ fields: { 'profile.username': 1 }});
});
You might also restrict the set of other users that is published based on them being connected in some way to the current user to avoid publishing all users all the time.
You should also avoid publishing the services key which contains security information about the user (ex: the bcrypt of their password). As #David Weldon points out in the comments, you shouldn't put other security information in the profile either and you probably want a deny rule on the user modifying their own profile from the client.
Our requirement is something like this.
We are building a multi-tenant website in ASP.NET MVC, and each customer should be able to create their own users as per predefined user roles.
We are thinking about to create a schema for few tables which would be common for customers. So customer can login to system according to their schema logins and we need not to alter any queries to serve all of them.
We are referring http://msdn.microsoft.com/en-us/library/aa479086.aspx Shared Database, Separate Schemas.
Can someone suggest on following
1. After creating schema how to authorize user against a particular schema
2. Is this possible that without any changes in queries db can serve multi-tenants
Thanks in advance
Anil
After much research, I can say that, although it takes more development up front and more checks along the way, shared database and shared schema is the way to go. It puts a little bit of limits on how easily you can cater to a client's specific needs, but from my point of view SAAS isn't about catering to a single client's weird needs. It's about catering to the majority of clients. Not that it's a SAAS but take iPhone as an example. It was built to cater to the masses. Rather than focusing on doing everything it's built to be one-size fits all just by its simplicity. This doesn't help your case when it comes to authoriztion but it'll save you dev hours in the long run.
If you are asking this in the context of SQL Server authentication/authorization mechanism, i can asnwer this question with saying that every user has a default schema which helps query engine to find out required object in the database.
SQL Query Engine will look at the user's default schema first to find the required object (table). If it founds the object in user's schema then use it, otherwise goes to system default schema (dbo) to find it.
Check this article's How to Refer to Objects section to find out how it works. The article also has some information about security concepts related to schemas.