Symfony 2 track anonymous user actions in database - symfony

I would like to track anonymous user actions as if the user would be authenticated. The goal is to let users perform actions(normally reserved to authenticated users), save it in Database with a special status (not visible until user will log into the application).
For example,
an anonymous user reply to a comment.
The system detect that the user is not logged in, save the comment with special status 'waiting for authentication'.
The system ask user to log in, in order to complete the registration of the comment.
User log into the application.
The system check for 'waiting for authentication' status and update/associate entries to the user authenticated.
Have you any suggestions / experiences to implement this type of functionality? Maybe Symfony has already in feature/bundle for that?

What you are trying to do is simillar to Lazy Registration, which is a proven concept. It is well implemented here at stackoverflow. It allows you to post messages after providing an email address. It works similar to this one:
http://www.90percentofeverything.com/2009/03/16/signup-forms-must-die-heres-how-we-killed-ours/
However, if you really want to go your way, without asking user for an email address, I would recommend storing data at browser local storage. It would save you a lot of work on backend side. Data would be transferred to the backend only when user registers. This way you will also prevent database pollution with users who never registered. http://blog.teamtreehouse.com/storing-data-on-the-client-with-localstorage

You could use ip address but it won't be very effective because one user can access your website from many ip addresses (wifi, 3g/4g connection ...).
You can rely on cookies but once he logs in from another device you can't do anything about it.
IMO, you should save actions and link them to a uniq token that you send to the anonymous user, once he's authenticated he can provide the generated token and then you save actions for that user. Becareful to not forget removing saved anonymous-actions once they are "identified".

Related

PermissionOffer for Non-Registered User

I have a use case where I would like to share a realm with a user that has not yet registered with Realm Object Server. The registered user would share a realm with a non-registered user by entering their email address. When the unregistered user registers using the app, they will be granted permission to the realm the first user owns.
How do PermissionOffers work if the user id doesn't yet exist? If the user id is an email address, can the PermissionOffer just hang until a user with the email address is created? What is the suggested workflow for handling something like this?
Permission offers are not bound to user Id. Instead, when you create a permission offer, a random token is generated that the first user sends via any medium (e.g. email/imessage) to the second user. The second user then accepts the offer by consuming the token and receives permissions to the Realm.

Sharing user ID's as a way to find people

Is it safe to share a user's ID that Firebase creates when a new user is created? I'd like to use it as an easy way to find other people on my platform.
I don't see why it should not be safe, so if it is. Please enlighten me :)
I am not too familiar with your system or how Nintendo does this (not really a gamer) but you can build something like this:
You can display the list of users (using uid, displayName and photoURL which can be obtained using the Admin SDK or by a list you maintain in the Firebase Database, Firestore, etc) to an authenticated user.
Let's say that user wants to add a connection or friend, you can get that user's ID token, the friend's uid and then add that user's uid to that authenticated user's pending connection list after you verify their ID token.
On the other end, you want the other user to accept the connection request (assuming this how your people finder feature works in your app). You would show the list of pending requests. When the user accepts the request, they would send their ID token and once that's verified, you can consider the connection completed.
To summarize, you still need an ID token to confirm the user sending the request and the one confirming it. Otherwise, if you just solely rely on uids, any user can get the uid of other users and try to add them to each other's friends list, etc.
Hopefully this points you in the right direction.

Google OAuth Always Showing Consent Screen

I'm building an installed application that will have features requiring the Google Drive REST API using Qt and C++. I understand Qt is now releasing new libraries to support OAuth flows but let's assume I'm a student and learning to use OAuth at this layer is a requirement for this project.
In my application, I have a working OAuth flow for installed applications that ends with an Access Token and Refresh Token being stored using QSettings (I'm open to input on whether this is a disastrously bad idea too). The application requires no authentication/login for its own sake/data, but it does need authentication to Google for calling API's using an Access Token. This application has no associated web backend being hosted; its simple and should be deployable completely locally (I've written and included a simple TCP server that will receive the authorization redirect_uri and will run and close when called from within the application).
As such, I'm curious about the best way to make sure that, when a user opens my application and wants to use the Google Drive features, they are appropriately authenticated on Google's end. Say, if I maintain an access token in the registry, and this access token is granted per-user/per-application basis (right?), then how can I make sure only the user the token belongs to is able to make calls to the API with it?
Here's my understanding and approach; feel free to correct me or educate me if I've got the wrong interpretation.
If an Access Token is found, perform the following:
Open a browser page to a Google login domain and have the user authenticate there (this could prohibit a user from being able to use a cached login session that would have access to a token they otherwise shouldn't have access to)
If user has correctly authenticated with a Google account, return control to the application and make a test call to an API using the stored token.
If the call fails (responds with an invalid_credentials) I should be able to be sure its because the access token has expired and the application will go through the flow to renew an Access Token from a Refresh Token.
If no Access Token is initially found:
Start a normal OAuth installed application flow
Get the tokens and store them so that when the user opens the application next time the former procedure is used
My issue then is the first two steps if the Access Token is found. Nominally this could be done by the typical OAuth flow but it appears that when using a localhost as the redirect uri, Google will always prompt for consent, regardless of settings for prompt and access_type authorization query parameters.
What can be done to accomplish these first two steps in a way that my application can control (i.e. not a solution that relies on a backend server being hosted somewhere)?
If this question is too open-ended for SO requirements I can make some more restrictions/assumptions to limit the problem domain but I'd rather not do that yet in case I unknowingly rope off a good viable solution.
Thanks for reading! Sorry if its a verbose; I wanted to ensure my problem domain was fully fleshed out!
If you are using an installed application, I wouldn't recommend using or storing refresh tokens. Storing refresh tokens on the client side means that if an intruder gains access to the client's application, they have infinite access to the user's application without ever having to enter the user's credentials. If you do insist on having a refresh token, ensure you follow the Google's installed app flow, with the code_verifier parameter included in your requests.
If the access token is found, you should try to verify it, and if verified then use it at the google api, otherwise force the user to login again (or refresh it if you chose to still use refresh tokens).
If no access token is found, your flow sounds fine.
A few notes on loggin in with Google:
Google will only return a refresh token if you specify access_type=offline in your auth request.
Google will only return a refresh token on the user's first authorization request, unless you always specify prompt=consent in your query params.
In my experience, when leaving out the prompt query param, the user is not prompted for their consent again. If they are logged in to google, you will get a new access token, but no refresh token, unless you have prompt=consent.
I think the idea is you use prompt=consent if you have no record of the user ever using your application. Otherwise if they have used it before, you may prefer to use prompt=select_account to allow the user to select which account he wants to use in case he has more then one, or you can just use prompt=none.
This is just my understanding of it all.
My approach I ended up using was just to deploy with an SQLite db that will be stored in the AppData roaming directory. The db schema includes a field for the user's Name (from the OpenID IDToken field if it exists), the user's picture URL (again from IDToken if it exists), the refresh and access token strings (will be stored as encrypted strings when I get around to it), the user's UID/sub string, and a field for a user name and password.
These latter two fields are authentication fields for within my own application, which, again, I wanted to avoid but it seems impossible to do so. So the user will be prompted to enter a username and password into a form, and these credentials will be checked against the existing SQLite db file mentioned previously.
If they exist and are correct, the user gets logged in and will have access to their respective access and refresh token.
If the user has forgotten their password, they'll be asked for reconsent (going through the installed app flow again), and whatever password they provided during initial login will be used as the reset password. It is considered, for my purposes, that logging into Google for the installed app flow is proof enough that the user account belongs to them and they should have authorization to reset the password.
If the user is a new user and doesn't have a record in the local SQLite db file, then they can also click a button to "Create New Account" - which effectively goes through the authorization flow as well but this time a whole new record is posted to the SQLite db with the appropriate fields filled.
There's still more optimization that could be done but at least I am getting closer to the level of security and control of access to Google user accounts that I want.
I'm not marking this as an answer because I feel like this solution is still not desired and that there should be an easier way. So if someone has evidence or experience of providing an equivalent level of authentication control without needing to maintain a local user account database then I would be more than happy to mark such a method as the solution!
Thanks again!

How to provide the Write Access in Firebase without giving Read Access?

I am having a strange situation in my app where Unauthorised users can send me the messages. whereas It will be only one user who can have the read access to those messages.
I am using the $bindto to write on the database (with my google logged in and google authentication enabled) and reading it through email password authentication method .
I want that user could send the message without any authentication process.
Is this possible?
There is no way we can stop unautheticated user to get the data from firebase database. For this situation that I faced I was worried about that if a user download the JS file he can get the access of all my database. But there is a catch :
Since you whitelist your IP/domain name no one other than that domain can take the access.So, even if they download your file they will no be able to get the access as request will not be from authenticated IP/domain name.
The other way is using the anonymous authentication method so that u can anyhow authenticate user and by that you can atleast have the trail of who are working or modifying your data (IP tracking access log is also useful).

Security design, maintain email but not linked to associated data?

my friend and I were thinking of a Web idea and ran into an issue:
We can't allow the email address to be sitting in a database with its associated data, in the case of a hacker obtaining the database. We'd like to ensure the email address and its associated data can never be linked, but then on the other hand we also need to keep them linked somehow so we can send users email notifications E.T.C
Can anyone think or know of a way around this? (.NET, Umbraco)
Thanks!
Have 2 databases, one with users + data + user id, another with user id + email. Secure them both, if one gets discovered, the other one might not be.
In any case you are asking us to prove falsity. ^^
I can't think of a way to link user data with emails without actually linking user data with emails. However, it would be possible to not have the email address stored and linked in a database if you could live with only having their email address when the user is logged in.
You could require users to log in using their email address and password as many sites do, but you could store a one way hash of the email address (such as sha1(email+password) ) rather than the address itself. When the user logs in successfully, you can store their email address in their session without ever having to get it from the database. You could then send them emails until you destroy their session. This would prevent an attacker from connecting their data to their email without brute forcing the hashes or grabbing the session information from memory or user cookies depending on how you store it.
Unfortunately, this wouldn't allow you to send notification emails.

Resources