Sign-in with Google without Google Sign-In JavaScript Platform Library for web - google-signin

I want to add "Sign-in with Google" as an alternative to creating an account when signing up for our services.
I want the process to retrieve the user's email address and name. That's it.
And this example was all I needed
https://developers.google.com/identity/sign-in/web
Worked great. Very similar to Log in with Facebook, which I added last week.
But now I read that it won't be supported after March 2023.
Using the destined-for-the-dustbin JS code, I can get back useful info about the account I'm logging in with.
ID: 10855600*******690837;Frank;Hart;frank.hart*****#gmail.com
The parameter passed to the callback function has a getBasicProfile() method which does the job
var profile = googleUser.getBasicProfile();
But using the new code, I found (by trial and error) that the parameter passed to the callback function is an object, which has three fields, the only potentially useful one called credential, with content such as:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjQ2Mjk0OTE3NGYxZWVkZjRmOWY5NDM0ODc3YmU0ODNiMzI0MTQwZjUiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2Mjg4NTQzOTcsImF1ZCI6IjY1MjE0Nzk1NjY0My05aWVmdHN2bmZraDVma2x1NHUxOGg1Ymc3MDA0YjdsOC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwODU1NjAwNDY3OTg0NzY5MDgzNyIsImVtYWlsIjoiZnJhbmsuaGFydDA0N0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNjUyMTQ3OTU2NjQzLTlpZWZ0c3ZuZmtoNWZrbHU0dTE4aDViZzcwMDRiN2w4LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkZyYW5rIEhhcnQiLCJwaWN0dXJlIjoiaHR0
Now, my guess is that I have to send that string to my server, and do something with it, possibly involving the "Client secret" that is associated with the App on developers.google.com. But I've been looking most of the day, and I'm not sure if what I've found is necessary - I hope it isn't
https://developers.google.com/identity/sign-in/web/backend-auth
Do I now need to become an OAuth2 programmer just to add a Sign-in with Google button?

The good news is that you do not need to learn OAuth2, you do not need to follow the backend-auth guide linked in your question. This migration actually removes the complexity OAuth2, access and refresh tokens from sign-in. Yes, there is the difficulty of learning and understanding the new and different way of securely sharing the user profile. Hopefully, after cresting over the learning curve you'll see how this makes working with a profile more simple.
JSON Web Tokens (JWTs) are now used to securely share the Google Account profile.
That big pile of text--the credential, it is a base-64 encoded and a JWT.
jwt.io has an online JWT decoder that's handy for testing and a nice writeup of working with JWTs. After decode its just a JSON object, no get methods are necessary, just access the individual fields.
All this said, you need to decide whether decode should take place in the user's browser, or on your backend server. This depends upon how you're working with the profile and your setup. Typically, you'd decode on your server after a redirect using data-login_uri in HTML or login_uri in JS.
There are a large number of JWT decode libraries available, so it's very likely you'll be able to add a JWT library, decode it and you're all set to access the individual fields in the credential.

Related

Is it possible to fetch my company updates feed without login

I'm trying to find a way to retrieve my company updates feed. The question is, is it possible without user login/ interaction?
When searching the docs I found https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api to retrieve this information. But if I'm correct, you can't do this without first logging in (r_organization_social requires 3-legged).
Is there another endpoint that could do this with only a key/secret? Or is the only way for this to work, login and make a cronjob that automatically refreshes the token. With the downside that I need to login again if the cronjob fails.
Some other relevant info, when trying to generate an application token I get the following error "This application is not allowed to create application tokens". But I think this is normal because a 2-legged OAuth is not available for Marketing APIs.
to summarize:
I want company updates feed without user interaction
Maybe using the wrong endpoint
Maybe something wrong with the app creation
Maybe something wrong with generating Application key
Credential docs used: https://learn.microsoft.com/en-us/linkedin/shared/authentication/client-credentials-flow

passing sensitive information to Firebase Cloud Functions using parameters

I'm trying to implement my own way of resetting user password for my mobile app. I've come to an idea to use cloud functions as I don't want anything other than Firebase working with my app. The problem is I will need to invoke three cloud functions to reset user password. First one will contain only user's email, second will contain code obtained by user from his password reset email and his email to check if code is valid and third one will contain his email and new password to set from cloud function.
The problem arise when I think about ways to pass this information into cloud functions. I know I can use URL parameters or just send it using POST method. But package that I would like to use to communicate with cloud functions doesn't support any other option than passing URL parameters to cloud function. I know I can write my own HTTP request to pass information using post but I'm thinking if there is any problem with sending this information using URL parameters. It's all sent over HTTPS which should guarantee obscurity of this data. I know that it still can be logged on server, and I don't know if Firebase store logs of cloud function requests with full URL parameters part visible. If yes, it would be big security issue with my app.
So, there are my questions:
Is there a security issue with passing sensitive information through
URL parameters?
Should I create my own solution using plain HTTP requests to pass sensitive information using POST?
Does anyone know if Firebase stores logs with visible URL parameters?
Is this even good idea to use cloud function for this matter? Maybe I should handle it differently?
Just to answer this question for future people like me:
like Renaud Tarnec said in his comment. SSL certificate by default ciphers all URL parameters. So it's safe to pass information this way. Firebase DOES NOT store logs with visible URL parameters when you call cloud functions. It only stores an ID of called function in your logs, so it's not a security threat.

Drive API OAuth2 with HTTPS Only

I have been studying the DriveAPI for a while now and can't seem to find a simple way to get it to work just for MY needs only...
I would like to use the DriveAPI only with just the REST API (HTTPS).
There are many things like token, clientid, apikey, secrets, etc.
All I need, is to search MY OWN GDrive files (FULLTEXT CONTAINS) and get a result from the API but I can't get it to work.
Please remember, this is for my own needs only and I would like to bypass the verification (login) window and get some kind of token, that lasts forever, so I can implement this in my own tool.
So, how can I authenticate and use the DriveAPI with just plain HTTPS?
My efforts so far:
I have already made a client ID and a client KEY for a sample project in the dashboard. I have also an Google Drive API KEY. From this point, I don't really know where and what to send.
As I mentioned in my comment, there is no "bypass" for the OAuth 2.0 authentication (that's why there is authentication enforced in the first place). Have you done any coding for this that you can share? For most REST API's OAuth 2.0 authentication is required. Your application must be able to request the token and use it to make the requests.
Google API's use Google Identity service to provide the tokens. In the following document there are many examples of how this implementation should be done in different programming languages:
https://developers.google.com/identity/protocols/OAuth2WebServer

Asking the user for settings when enabling an Alexa Skill

I am working on an alexa skill which uses an external web service which requires an API key.
I can't find for the life of me where I can add this property in so that when the user enables the Alexa skill (I haven't got as far as publishing yet but I assume there is a property I can set somewhere as well for testing) they can add their API key and I receive this within my node.js lambda function and extract it and use it for my post request to the web service.
I know there is an Amazon Account Linking Service, but the web service I am using doesn't support this type of login I believe, their API is only accessed by sending a header containing the API key. Therefore I need a way for the user to be able to store somewhere their API key so I can then post this to the web service from the lambda code.
I'm not clear on how you expect the user to 'add their API key'.
The only built-in UI is the cards that your skill can push to a user but these are very limited and can't request information from the user.
Amazon does not show the user any sort of configurable settings for the skills.
And you have noted account-linking and that it does not address your needs.
So you could either ask the user to say the API key, which would be much too error prone unless it is unusually short, or you will need to direct the user (probably via a card) to your own website where they will provide their API key.

In my meteor app, how do I make authenticated google API calls on behalf of my user?

Background: This is my first standalone web development project, and my only experience in Meteor is building the Discover Meteor app over the last summer. I come from about a year of CS experience as a side interest in school, and I am most comfortable with C and C++. I have experience in python and java.
Project so far: I'm creating a calendar management system (for fun). Using accounts-google, I have created user accounts that are authenticated through google. I have requested the necessary permissions that I need for my app, including 'identity' and 'calendar read/write access'. I've spent the last week or so trying to get over this next hurdle, which is actually getting data from google.
Goal: I'd like to be able to make an API call to Calendar.list using a GET request. I've already called meteor add http to add the GET request functionality, my issue comes with the actual implementation.
Problem: I have registered my app on the developer console and set up Accounts using the client ID and secret, but I have not been able to find/generate my 'API key' for use in the request. Here is the google guide for creating the access token by using my (already) downloaded private key. I'm having a hard time wrapping my head around an implementation on the server side using JS because I don't have a lot of experience with what is mentioned in the HTTP/REST portion of the implementation examples. I would appreciate some help on how to implement a handshake and receive an access token for use in my app. If there is a call I can make or some package that will handle the token generation for me, that would be even better than implementation help. I believe an answer to this would also benefit this other question
The SO answer that I've been referring to so far: https://stackoverflow.com/a/14543159/4259653 Some of it is in spanish but it's pretty understandable code. He has an API key for his request, which I asked this question to help me with. The accounts-google documentation isn't really enough to explain this all to me.
Also an unrelated small question: What is the easiest way to deal with 'time' parameters in requests. I'm assuming JS has some sort of built-in functionality that I'm just not aware of yet.
Thanks for your research. I have also asked a very similar question, and right now I am looking into the package you recommend. I have considered this meteor-google-api package, but it looks abandoned.
Regarding your question about time manipulation, I recommend MomentJS. There are many packages out there; I am using meteor add mrt:moment
EDIT: MomentJS now has an official package for Meteor, so use meteor add momentjs:moment instead of the mrt command above
Below is a snippet of what moment can do. More documentation here.
var startTimeUTC = moment.utc(event.startTime, "YYYY-MM-DD HH:mm:ss").format();
//Changes above formatting to "2014-09-08T08:02:17-05:00" (ISO 8601)
//which is acceptable time format for Google API
So I started trying to implement all of this myself on the server side, but was wary of a lot of the hard-coding I was doing and assumptions I was making to fill gaps. My security prof. used to say "never implement encryption yourself", so I decided to take another gander for a helpful package. Revising search criteria to "JWT", I found jagi's meteor-google-oauth-jwt on Atmosphere. The readme is comprehensive and provides everything I need. Following the process used in The Google OAuth Guide, an authorization request can be made and a key generated for making an API call.
Link to Atmosphere: https://atmospherejs.com/jagi/google-oauth-jwt
Link to Repo: https://github.com/jagi/meteor-google-oauth-jwt/
I will update this answer with any additional roadblocks I hit in the Google API process and how I solved them:
Recently, I've been running into problems with the API request result. I get an empty calendarlist back from the API call. I suspect this is becuase I make an API call to my developer account rather than to the subject user. I will investigate the problem and either create a new question or update this solution with the fix I find.
Fix: Wasn't including the 'sub' qualifier to the JWT token. Fixed by modifying JWT package token generation code to include delegationEmail: user.services.google.email after scope. I don't know why he used such a long designation for the option instead of sub: as it is in the google API, but I appreciate his package nontheless.
I'm quickly becoming proficient in this, so if people have meteor-related google auth questions, let me know.
DO NOT USE SERVICE ACCOUNTS AS POSTED ABOVE!
The correct approach is to use standard web access + requesting offline access. The documentation on the api page specifically states this:
Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data.
The only exception to this is when you are using google apps domain accounts and want to delegate access to your service account for the entire domain:
Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as "delegating domain-wide authority"
This makes logical sense as a user must be allowed to "authorise" your application.
Back to the posters original question the flow is simple:
1) Meteor accounts google package already does most of the work for you to get tokens. You can include the scope for offline access required.
2) if you are building your own flow, you will go through the stock standard process and calls as explained on auth
This will require you to:
1) HTTP call to make the original request or you can piggyback off some of the internal meteor calls : Package.oauth.OAuth.showPopup() -- go look at the source there are more nifty functions around there.
2) Then you need to create an Iron router server side route to accept the oauth response which will contain a code parameter that you will use to exchange for tokens.
3) Next use this code to make a final call to exchange the "code" for the token + refresh_token
4) Store these where ever you want - my requirement was to store them not at the user level but multiple per user
5) Use a package like GoogleAPI this wraps up Google API calls and refreshes when required - it only works when tokens are stored in user accounts so you will need to rip it apart a bit if your tokens are stored somewhere else (like in my case)

Resources