Why doesn't Meteor have server-side sessions? - meteor

I want to create a shopping cart with Meteor that allows non-logged in visitors to have persistent shopping carts.
As far as I can tell, the only way to track a non-logged in visitor in Meteor is to set a persistent ID on the client (localStorage) then pass that ID in every subscribe and method call.
Most web frameworks store a unique session ID in a cookie and that cookie is sent with every request to the server so the server always has a way to identify the visitor who sent the request - why not have similar functionality in Meteor?
It looks like Meteor persists the userId (if logged in) in localStorage and sends that userId to the server over the DDP connection - but that only helps when users are logged in. Why isn't this done with all visitors via a sessionId?
Am I missing something here? Other techniques are welcome - I just want to clean up my code and not have to pass the sessionId around everywhere.

You right meteor dont support cookies you can read more http://info.meteor.com/blog/session-cookies in here, my suggestion use local storage to persist clients without login. Also take a look to how to create UUID in javascript Create GUID / UUID in JavaScript?
//I commented first and post it here since I think this is the answer my two cents.

I'm guessing the cart is a field in your user collection schema.
Instead, make Cart its own collection and have userID be the foreign key.
Then, if the user isn't logged in, you can use the localStorage token as the ID: localStorage.getItem('Meteor.loginToken').
Finally, when the user signs up, in your createUser callback, you search for a cart with that token. If it exists, update it to the new userId.
This is also a little faster for analytics since you don't have to traverse the entire user collection to get the cart object.

Related

Does createCustomToken(aUID) logout users currently authenticated with that same aUID

TLDR; Can multiple different users be authenticated and retain authentication via a generated custom token IF that custom token for each of those users is being generated always by the same UID? That is, User1 gets custom token generated by UID1 (via createCustomToken(UID1)) and then signed-in with signInWithCustomToken(), THEN User2 gets and signs-in with custom token generated using UID1, then User3 same thing etc etc, can ALL these users happily remained logged-in and experience no interruptions despite these other users being authenticated in this identical manner?
Long Version:
Ok, so I am trying to create a link-sharing system wherein a user who navs to this link can access a specific subset of my project's Firebase resources.
I have already tried using Firebase's signInAnonymously() to do this, but I dont like the way that Firebase does this for a whole host of reasons I dont want to get into.
The way i want to accomplish this is by:
generating a unique link (really a Firestore unique doc ID with some access data stored in that doc)
having the unauthenticated user navigate to some landing page, calling the cloud function and passing that unique link (lets call it a UID now)
cloud function, upon recieving this UID, will createCustomToken(UID), returning the token back to calling user
and the user will authenticate themselves with signInWithCustomToken(returnedToken) and access provisioned resources
Now, that is all well and good, but my question is:
If two (or any amount more people) people navigate to that same link and therefore pass and create token with the same UID, will they all be ok to continue happily using Firebase resources? Or is it because they got tokens created for them which utilised the same UID a sort of token-conflict is made, and therefore any next user who authenticates in this manner will revoke the previous user's auth token.
I havent been able to try this, and it seems like every question asked about these custom tokens relates to the generation and expiry time of them, which I understand. I wish the Auth docs were more clear on the mechnics and pitfalls of using Custom Tokens. I also havent been able to try it myself as it would be quite alot of refactoring, and was hoping someone could give me a straight answer to this.
Yes, a user can login on multiple devices without affecting other sessions at the same time irrespective of which auth method you use.
I'm not sure what the unique links are but it's not a good idea to pass the UID itself around if you function just takes a UID and returns a custom token as UIDs are pretty short and just a random string. It might be best to add a custom signed JWT in the links that contain the UID in payload so you can verify them before creating Firebase Custom Tokens.

Managing Session Cookies, from Firebase Authentication, with Redis

I am using Google Firebase Authentication to handle user management for my web application.
Specifically, I am using managed session cookies. The problem I am running into is figuring out how to associate each session with a corresponding user.
For example, I would have two separate tables:
User - Stores personal information such as name, email, password, etc
Account - Stores account related information such as posts, friends, etc
I was thinking of using Redis as a key-value store for this situation and the flow would work something along the lines of this:
User enters credentials
Credentials gets verified by Google's backend
User receives ID token
User sends ID token to my backend along with user id
Google's backend creates a session cookie
Backend would store the session along with the user id into Redis
Whenever user hits a protected endpoint that requires user id, a call to Redis would be made
I thought this might work because, within my Flask API, if I print out the type of the session cookie, the value is of type string.
I was wondering if this is an overkill, or if there is a better alternative to achieve what I want.
After much research and discussions with peers who work in the software industry, I have decided to use the strategy outlined in the question.
Feel free to comment if you have anything else to add.
Cheers.

Firebase user login managing connection with API

I'm quite new to firebase and I am looking for best practices using it, maybe I will be able to get some advices here.
What I want to do:
User login using firebase.
Problem:
I save user info in firebase but use SQL server as database where I need that user information as userId
Question: How should I approach that?
Register user on firebase and when I get response with userId and token, save it to my sql database too?
what's my current approach:
At this stage we're thinking of creating new users via admin panel (and then these users can sign in)
Would it be good approach to add user to sql database, send email to finish registration (create pasword) and then add this user to firebase, and with response send request to my backend where I update user that he's verified, add userId and token?
It's very common to store additional information about Firebase Authentication users in your own database. Whether it's good in your use-case is subjective, but it's definitely common.
Assuming that you have a server interacting with SQL server on the user's behalf, be sure to pass the ID token from the client to the server, decode it there, and then use the UID (and other claims) from that token in your database interactions. Don't allow the user to just pass their UID, as that'd be a security risk.
For more on this scenario, see the Firebase documentation on verifying a user through their ID token.
Your approach with an admin panel is a common first approach, but not something I'd recommend. Since you'll need to allow the user's to sign in with email/password, there is nothing keeping them from calling the createUserWithEmailAndPassword API themselves on your project. So I'd recommend leaving the creation completely to the clients, and save yourself from having to consider that an abuse scenario.
If you want to control what users an access the data, store a list of email addresses (since you seem to associate that with uniquely identifying a user already) in the database, and check the email address in the ID token is in the list (and is marked as verified in the token).

Is it secure that Firebase uid is used / revealed on browser?

I am currently building one web application, and I consider to use Firebase auth and its database. My concern is that if user id is on browser, does it make any security issue?
For example, say that my user id is 12345, and I would like to show some information about user 12345 on a certain page. In order to move to the certain page that I can see user's information, I click some element (like a button), and go to the page. (Ex: https://localhost:9876 => https://localhost:9876/12345) In this case, the user id is visible, but I am not sure if this is reliable approach.
Thanks.
EDIT: I just noticed that security rules should be used thanks to Eric's comment. However, I am not 100% sure if the rule can be used for auth object too. For example, auth object is used to get user id, but using user id, is it possible for someone to obtain the user's email address which is stored in auth object? For instance, in the above example, someone might obtain user 12345's email address using user id, 12345.
The correct way to secure user related resources is via a Firebase ID token. Database/Storage rules already rely on this mechanism. You cannot just rely on the correct user ID being provided. That provides no security. Instead, before return restricted resources, you should check verify the ID token and trust only its content which includes the UID. FYI: the Firebase Admin SDKs already provide an API to verify an ID token.
Typically the way to pass the ID token (if you are not using real-time database), is as follows:
Single page app: you can call getIdToken() and then pass the latest ID token in the URL query parameter, post body or the header as you send an XHR request to your server.
Traditional website: you have to set a session cookie. The easiest way is to set the ID token as session cookie and keep updating it on expiration. On your backend, you will verify this before returning the user specific resource.

asp.net core identity claims vs properties (efficiency point of view)

i've read all the tutorials and questions asked about the subject but they contradict one another
claims(userclaims and roleclaims) are serialised into a cookie (along with custom identity user properties you specify by overriding the principle factory) but they don't get queried, they're stored in a cookie, which mean that the more claims a user have, the more data will have to round trip between the server and browser
a custom identity user property by default don't get serialised but get queried from the database, so every time you need that data it query it from the database which is more work to do on the database on each request if you frequently query for it
so which is more efficient and which is safer
for instance
IsAdmin should be a role/claim? but then if someone stole the cookie, nah nah, the cookie already contains userid/username/securitystamp, so even if it's a property, the userid on the stolen cookie would query on the custom identity user property, or is there something that will prevent this cookie from working when stolen ?
another instance
if i've 20 property for the user (first name, last name, address 1, address 2, postal code, whatever the case may be), should i simply have the user wait a bit for a bigger slower cookie to be send back and forth or should i do all the work from the db using custom identity user
but then, if i remove or add a claim to the user, would it be updated on the next request if it doesn't get queried or is the security stamp validate that this cookie is still valid ?
cause at the Task AddClaimsAsync of the userstore of efcore it only add the claim to the dbset
i apologize i know this is many questions to ask but the resources on the matter are not that good and one can easily get lost reading the identity source
Rule of thumb - put frequently added items as a claim, everything else can live in DB and be queried on demand. I.e. address 1, address 2 can't be required on every request, so keep them in the DB.
On the other hand IsAdmin (should be a role anyway) I can imagine will be checked on every request, so it should be in the cookie without having to query the db.
If you afraid of your cookies getting stolen, don't show them to anyone! set up SecurityStampValidator to do frequent checks - like every 5 minutes. This basically updates the cookie with the fresh information from your database and changes the cookie. So even if the cookie is stolen, it will only work for 5 minutes.
I don't think the two statements contradict, it depends on your configuration. The second statement mentions "by default".
You do not need to store all information in claims nor do you need all the information all the time. If you want profile information, call the server once and store the information on the client, or get it when needed only.
The same counts for authorization, in case you want to show / hide elements based on permissions. This may include a tag called "IsAdmin". Authorization should be kept close to the resource.
If your client wants to refresh the information, just call the server. Claims are not updated during each request. In general, the user has to log out and log in again. So Claims are not flexible and therefor not really suitable for properties that can change (frequently).
As for safety, it doesn't really matter that the client can alter the information, it is for display only. It doesn't change the permission in the backend.
You can consider to add something like a display name to the properties, if you are showing that in every page. You can also consider to implement caching to limit database calls. In the end it really depends on your requirements.
As for stolen cookie, you'll need to implement additional security to your server to detect suspicious behaviour. You may want to include the ip address as claim. As for the admin, add security, e.g. filter by ip address and / or use an additional code which was send by email.

Resources