Couple of questions about firebase functions.
I have a function that needs to verify that the current user is authenticated, and then use their userId to store some data and associate it to them.
How do i access userId and validate auth in the functions?
Where can i get the token that needs to be sent to server through http header?
To get started, look at the official sample code available in GitHub that shows how to protect an endpoint. You'll see that it takes a token from Firebase Authentication for the currently authenticated user using getIdTokenWithCompletion. The function uses the Firebase Admin SDK to verify the token. The result of verification is a DecodedIdToken object, which contains various properties, including the user's uid.
Related
The following scenario:
You have sensitive and protected user infos (name, mail adress, telephone number, adress) securily saved in an authorization server (e.g. IdentityServer4).
You have an API loading data from a second database storing your own data (not the sensitive user data). This data is somehow linked to users (lets say we store documents and the document A belongs to the user with auth-id "XYZ").
The problem:
Now a single page application gets a list of documents and wants to display the name and email-address of the user that owns the document.
So far I understood the OpenID Connect UserInfo endpoint to ONLY return the user info for the current logged in user but not other users. So there is the need to get the infos for the other users somewhere else.
Solution 1: Copy the user info into the second database. That would leak sensitive data out of the secured autorization server, introduce the need to keep the data in sync (if changed on the auth server) which introduces a connection between the auth server to the second db or the auth server to an API endpoint.
Solution 2: Let the API access the auth DB and grab the data from there. Possible but introduces the DB connection to the authorization DB what is (in my personal opinion not good).
Solution 3: Introduce an endpoint (like the UserInfo endpoint) on the authorization server that lets the single page application request the user info by auth id. Seems most practicable but seems not to be specified?
Is there an official specified/recommended way to solve that? Maybe a specification to use the UserInfo endpoint for that which I have missed so far?
simply my.domain.com/userinfo/XYZ that returns the infos for the user with auth-id XYZ???
Following is extracted from the OpenID Connect specification's user info endpoint section,
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User.
As highlighted section explains, it expose information about originally authenticated user. There is no way to obtain information about other users unless you have an OAuth 2.0 access token authenticated for them.
Also, embedding an endpoint to authorization server is not recommended. It brings maintenance burden as well as privacy issues. Also, this will prevent you from alter the authorization server (ex:- Your sell this app and that customer use Azure AD). So don't do such non-standard ways.
Proposed solution is to obtain the user name and email at the time user create this document. At the time of creating, I believe application have an access token authenticated to content creating user. So you can get claims from user-info endpoint and store them along with document. And when another user get the document, you can reveal user name and optionally email. May be you never reveal email but give the ability to mail the owner which would be handled at back-end.
I need to access several YouTube channels for my job to pull analytical data and export it to a database. The problem, is that this requires using OAuth, which would be fine except I don't know the controlling person's username/password. She probably won't give me her credentials since it's personal.
Is there a way to do this without explicitly using her username/pass? Like, she tried making me a content owner, but I still can't authorize this level of information.
This is exactly the reason why OAuth was created, to make requests on behalf of a user without their username and password.
Have that user generate an access token. Here are the Google Docs. In a nutshell:
Have your user send a post request to https://accounts.google.com/o/oauth2/token with your app key. The response should look something like:
{
type: "oauth",
token: "XXXXXXX"
}
Then, make an API request on behalf of that user with their token by passing in the token returned from the previous step as value for the Bearer filed for any web request to the YouTube API. This will allow you to perform an authenticated request without explicitly knowing the user's username and password.
The short version of this question is: If you use Firebase's OAuth capabilities to obtain a user's email address, do you still need to confirm/authenticate the user's email address yourself?
One of the usual benefits of using OAuth is that - depending on OAuth provider - you can get a confirmed email address, but is this really the case when using Firebase for a webapp, e.g. with a binding like AngularJS?
After a user authenticates, there seems to be two data objects - authData available to the client side, and auth available for security rules on the server side. While authData contains details such as name and email, but auth contains just a Firebase uid plus provider. Therefore, if I am to obtain that user's email address, it must be provided by the client, and hence can't (in theory) be trusted?
Based on my understanding of Firebase's documentation, if I were to use GitHub OAuth for my app, I'd need to do something like the following:
Get user's to log in/create account with Firebase/GitHub
Client JS retrieves the email address from GitHub OAuth response
Client JS "submits" this email for confirmation - could be done multiple ways
Email address should be saved in Firebase with status "unconfirmed" (such a field being read-only to the user)
I need my own server-side logic to process such email submissions and send a confirm email request, e.g. through something like Mandrill
I need additional server-side logic to receive the clicked confirmation and mark the email address as "confirmed" in Firebase
Therefore Firebase can help me with steps 1-3, but steps 4-6 need to be done via my own server-side code?
The answer to this question is therefore a Yes/No, but with some justification/explanation!
Thanks to #Kato for confirming my assumptions in the question were correct, so I'll explicitly provide this as an answer, as well as provide an alternative I hadn't thought of.
So the short answer is, "Yes, you need to obtain or verify the user's email yourself when using Firebase OAuth", and the steps I listed above is one way.
An alternate approach that still requires server-side code but doesn't require emailing, would be to have the user write their token to their users table entry and then have server side code use that to retrieve the verified email address from the provider themselves. e.g. with a GitHub authorization token and appropriate scope, you can retrieve the user's verified email and not then need them to verify it to you again.
I am attempting to use Google's OAuth services for iOS and am passing the following scopes into the auth mechanism:
https://www.googleapis.com/auth/plus.me
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
As far as I can tell the login is working correctly (I am prompted for my Google credentials); I can parse out my email from the GTMOAuth2Authentication object, but my question is, how do I get the data from "userinfo.profile", i.e., Name, Gender, etc.
Thanks
You may use the access token to acquire the user's basic profile information by calling the UserInfo endpoint.
See https://developers.google.com/accounts/docs/OAuth2Login#userinfocall
I am trying to impliment Oauth for my webapplication for google.I am worked upon a POC and it working fine but i have a confusion and not sure how best it can be achieved.
I am using scribe java API for Oauth.
here are the steps i am performing.
Getting request token from Google.
Redirecting user to Google to authenticate them self and authorize my serivice to access his/her few details.
get Access Toekn from google by providing request token and verification code given by google.
Accessing user info once google provide Access token.
now my main confusion is at step no 3, since i am working on a web-application so it will be a 2 step process.
Redirecting user to google
Handling back google redirect.
In order to get an Access token i need to provide same request token which i got at step1 else my request being rejected by the user.
The request token contains 2 things
Toekn -->which is based on the registered application so not an issue
Secret-->This is always being a random string so it should be same when asking for access token
that means i need to store this secret either in my session or some where so that i can access this secret when user is being redirected back to my application.
My confusion is,since in order to save it in session i have to create a unique key and some way to access it in the other action class which will handle Google Redirect back how can i achieve this since at a given time so many user can ask to login using google.
any help in this regard will be much appriciated.
Thanks in advance
When you receive the request token + token secret, use the request token as the unique key of your session to store the token information. After the authorization process, in the callback url, you have access to the request token (it's one of the parameters passed to the callback url). Using this parameter as the session key, you can restore the token information from session, including the token secret, and use it to sign your request for changing the request token for access token. After receiving the access token, a new token secret is returned to you and you can delete the old one from session.
how can i achieve this since at a given time so many user can ask to
login using google
This is not of any problem because for every single user on your site, you are given a different request token.