I need to send emails from my server, through simple REST calls, from my backend-server email address, to the email addresses registered in the system.
But there is a problem, bear with me.
The thing is a lot of the documentation I've seen so far seems to assume I want to access the clients gmail data, which I don't, I only use the client's address as a destinatary.
A lot of the examples I've seen, involve a visual promt to authorize the access to the api.
BUT WHY?
They assume I'm gonna be making apicalls from a mobile device, acting on behalf of the client, which needs a visual prompt for consent. But none of that applies to my use case.
The thing is, there is ever only gonna be one sender, "ME" (the company email designated for the backend server).
I should be able to create a secret api_key on the google console, and send that in my request headers (like freaking FIREBASE does), or use that key to generate a token which I then send to the api endpoint (like Paypal does).
I want to be able to do something like:
POST https://gmail.googleapis.com/upload/gmail/v1/users/{userId}/messages/send
Authorization: key=<key_created_on_google_console_or_token_obtained_using_said_key>
{
message stuff...
}
The api reference on google says that I need to create an authorization using OAuth credentials, which I'm then supposed to use to create a short lived token that is inserted as
"Authorization: Bearer <TOKEN>"
in my next apicalls, until it expires. But...
In the console, creating a new OAuth2.0 client ID, says I need to create an app. But I already have a proyect and an api_key (with permissions to gmail api). And that said app is gonna have to be sent for review!. What's going on?.
So..
How do I send emails, from my own-controlled email address, using REST calls.
It's all server side, no need to access any user data (not even my own), I already control the sender address, I already have created a project on google console, I already created an api_key.
OAuth seems to think I'm doing something I'm not, so what am I missing?.
Thanks.
The Bearer token is an OAuth2 access token that you get after authorizing your app to access your Gmail account. It's designed for 3rd party authorizations really (like your users allowing your app to access their Gmail) that is why it seems complex when you're accessing your own account.
Check this out https://developers.google.com/identity/protocols/oauth2
Turns out I was trying to use the wrong tool for the problem.
After looking for alternatives I found out about MailGun and SendGrid.
Tried SendGrid and it fit like a glove. Love it.
I was using Gmail+PHPMailer for this problem and thought the new api was meant to replace that, but turns out it's not.
Alexey pointed out the intended use in his answer. Actually I might end up integrating the new Gmail api more in line with it's intended use on my clients mobile devices.
It was all my missunderstanding.
Thank you for your time.
Related
I am trying to create a web app for my server which can connect my website forms to Google Sheet. While generating the OAuth client ID and Secret I chose "webserver" and I needed to enter a call-back URI to handle the authorization code returned back from Google as a response.
Well, now I created another client id, but this time I chose Application type as "Desktop" and I didn't need to enter any redirect URI. In my PHP app, I used redirect URI as urn:ietf:wg:oauth:2.0:oob.
However, in both cases, I was able to get Access Token and Refresh Token and my Google Sheet API working smoothly.
So my question why I should choose Application Type as "Webserver" and do an extra step by entering "Redirect URI"? What is the benefit of doing so?
You may check a Quickstart Oauthflow here https://developers.google.com/sheets/api/quickstart/php#step_1_turn_on_the
So my question why I should choose Application Type as "Webserver" and do an extra step by entering "Redirect URI"? What is the benefit of doing so?
Security. Web server client will return the auth to your server. Installed will return it to where ever the request came from. If someone got your client id and secret for a web app they couldn't use it. However if someone got your client id and secret for an installed app they could easily use it to impersonate your developer account.
What is client id and client secret.
Think of the Client id as a login and the secret as its password. This login and password identify your project to Google and they identify the developer of that project as you.
You the developer are responsible for this login and password. If it is stolen then as far as google can see it is your application using it google has no way of knowing other wise. If the login and password for a desktop app is stolen someone could put up an app and as far as anyone would know it would appear to be your app.
You create super awesome email app which gives access to a users gmail account. It becomes very popular and a lot of people know the name. Someone steals your client id and secret creates an app that looks exactly like your super awesome email app. There is no way for anyone to know its not. Because its set up as a desktop app this person could then put it up and start harvesting authorization from your potentiate users without them having any idea. It looks exactly like your app only the responses are going to urn:ietf:wg:oauth:2.0:oob which is the host server of the person who put up this app to mimic yours.
Unless your application is running on a users machine its really not a good idea to use installed credentials. That being said theirs nothing to stop you from doing so it will work.
I know I'm probably going to get a "no, you can't do that" but it doesn't seem reasonable to me.
My client uses Quickbooks Online and wants to be able to have his customers sign in to his web site and see how much they owe, and then pay their invoices with a credit card.
Obviously, the customers themselves can't be signing into Quickbooks Online. We want the web server to be able to directly access the data via the api.
I've found the api but I'm not sure if it's possible to have the webserver connecting to it and getting the data it needs.
I know this can be done with other systems. I've done it with GMail and Salesforce using OAuth2.
The biggest piece I want to load from quickbooks as well might be something unavailable as I couldn't find it in the API anywhere. When my client opens Quickbooks Online, he can send an email to any customer that will include a link to pay online by credit card. We'd like to be able to find that link and redirect the user to it. But I'm not sure if it's available via the api.
I could go with webhooks but that would require storing all that data on our webserver, and syncing it for existing data. Not to mention what happens if an update happens to fail.
You're misunderstanding how OAuth works a bit, which is what is causing the confusion here.
The person who owns the QuickBooks company logs in, not the end-user. They log in ONCE, and that gets you OAuth tokens that you can use to make server-to-server calls forever going forward.
Soooo...
I know I'm probably going to get a "no, you can't do that" but it doesn't seem reasonable to me.
You can do what you're trying to do, you're just going about it the wrong way.
Obviously, the customers themselves can't be signing into Quickbooks Online.
Correct.
We want the web server to be able to directly access the data via the api.
That's fine, and totally do-able.
I've found the api but I'm not sure if it's possible to have the webserver connecting to it and getting the data it needs.
It is do-able.
The key understanding here is that you're going to have an OAuth connection process that the person who owns QuickBooks is going to go through just once, to get you OAuth tokens.
You're then going to store those OAuth tokens server-side (e.g. in your database).
You can then use those stored OAuth tokens to make future server-to-server API calls whenever you want.
When my client opens Quickbooks Online, he can send an email to any customer that will include a link to pay online by credit card. We'd like to be able to find that link and redirect the user to it. But I'm not sure if it's available via the api.
I don't think this information is available via the API right now.
There is an API endpoint to send an email invoice, if that's helpful:
https://developer.intuit.com/docs/api/accounting/invoice
Our application can show rich links to webpages. So instead of a mere weblink we show a short summary and a picture. We used to use embed.ly's extract api to supply us with this data, but since they have changed their terms and pricing we have implemented an alternative solution.
The problem we find is that linkedin profile urls cannot be assessed by our new solution. Embedly was able to give us all the details we needed from a linkedin profile url (including the user's picture), but we don't seem to have access to that information without going through linkedin's API.
This call gives us all the data we are looking for:
GET https://api.linkedin.com/v1/people/url=[PROFILE_URL]:(id,email-address,first-name,last-name,headline,summary,formatted-name,picture-url,picture-urls::(original),site-standard-profile-request,public-profile-url)?format=json&oauth2_access_token=[TOKEN]
Where [PROFILE_URL] is a linked in profile url and [TOKEN] is the oauth2 access token.
There are two issues that I have:
Our application does not ask users to authenticate through linkedin, so we do not have a user oauth2 access token available;
Linkedin's suggestion in their FAQ (https://developer.linkedin.com/support/faq) seems very daft:
Can I get an access token for my application that doesn't require a member to login?
We do not provide access tokens for applications that are not associated with a particular LinkedIn member.
If your application requires you to make API calls in an automated way - without user interaction, you need to bootstrap the first access token request by manually signing in, and then ensure that your application refreshes the token automatically prior to expiry to avoid the need for additional human authentication.
Now... four questions:
a. Has anyone implemented option [2] in a production setting?
b. If yes, what are the limitations, downsides etc. Is this really the best and safest solution?
c. Is there any alternative that allows me to authenticate the application itself with its mighty client key and client secret?
d. Is there anyone from linkedin monitoring this? If yes, can you contact me?
Cheers, Raymond
I have a j2me project on blackberry that needs to connect to twitter. I did most of the hard stuff already, I've got an api that guided me through to the access token pretty easily. Now I can't seem to get the authentication to work with a status update in REST.
I know my tokens are valid because if I run a GET method like verify credentials, it's fine, everything is valid. But POST messages are just confusing me. Am I supposed to pass in a whole consumer key, signature, oauth version, etc every time I update a status? Or do I just pass the access token? Are they all supposed to be POST variables or just the ones specified in the twitter api as parameters. The twitter api documentation has left me completely lost.
If someone had a link to a site that had examples of all of these messages put into plain text NOT in an library as 99% of tutorials for this situation are, it would be really helpful.
I asked various questions about my problem (here and here) and I also asked in the #oauth & #openid freenode's channel on IRC. (this is note an "UP" question, it's an other problem)
I'll sum up my project configuration : Anyone will have the possibility to create an app that can use my API. To start, I'll work on my API and a Web based app, but the documentation about the API will be public. It's a bit like Twitter API.
The problem I face is how can I be sure which user is using the API (to retrieve his personal data, like your tweets), even if the User is using an app that I don't know who make it (again, like twitter and all the apps around).
I googled a lot and with the help of the previous answers given, I took a look at OAuth.
As far as I understood the way OAuth works, here how :
A user visit an app that use my API (web, mobile, whatever)
The apps redirect the user to the API for the authentication (I'll use OpenId) and the authorization (OAuth). This is a bit odd since the API will have a web interface for the login and the authorization (I suppose this is how it works since Twitter do that)
The API redirect the connected user to the app, with some tokens. In these tokens, there is a token representing the user that the app must store in order to indicate to the API which user is using it currently (Am I correct?)
So far, everything goes well. But what I can't figure it out, is when the user quit the app and goes again : how the app can remember the user is the one that used it before ?
(Before some of you bring me the cookie answer, I'll remark this is a simple example, it would be the same if the user clear his cookies, format his computer or change its computer.)
The only solution I can find, is when an unauthenticated user (without a remembering cookie for example) goes to the app, the app redirect him again to the API to authenticate himself, but this time, the user won't have to re-allow the app (authorization) since it already did it. The API will then return the user to the app to allow him to play with this.
Is this the proper & secure way to do it ?
The #OAuth IRC channel told me about the new protocol, WebID, but this is currently in pre-draft mode and I don't want to use something that will change continuously in the future :/
Thank you very much for your help!
Short answer: OAuth results in an authenticated access token. That access token is tied to ONE user. And as long as the access token is valid. The third application can do whatever the API allows the access token to do.
Long answer:
The thing with OAuth is that it does not "Log in" a user. OAuth gives third party applications what is called access tokens which can be used to access data on behalf of a user whether he/she is logged in or not.
Many services restrict their access tokens. Twitter for example issues two types of access tokens, read-only, and read/write. But there is no concept of logging in to use APIs. While an access token is valid, a third party application can access the user's data, and change things without a user's explicit interaction.
Most API providers have functionality to revoke access tokens. That is what happens when you in twitter look at your Connections page . See the revoke access links?
Personally I love the OAuth approach. As an API provider, you can control what access tokens are allowed to do, and the user can kill bad applications from using his/her resources. OAuth is secure as far as authentication goes. Third party applications do not get hold of user's passwords. But once authenticated they can do whatever your API allows.
if we take a look at how Twitter works, I think the missing point is an other layer to the project: The Official website:
The thing is, when you want to allow any 3rd party application to use Twitter, this application redirect you to the OAuth page of the Twitter API, IF you are connected, but if you aren't, it redirect you to the login page, which is located at http://api.twitter.com/login
(I don't know if keeping the api in api.twitter.com for loging an user, instead of just twitter.com is correct, but this is just semantics)
So, the workflow would be:
A user goes to a 3rd party application (like a website)
This third party redirect the user to the API for Authorization
The API redirect the User to the website for Authentication first
The official website redirect the User to the OpenId provider (or Facebook connect)
The Authentication is made (via multiple requests)
The website redirect the user to the API after he's successfully authenticated
The user allow/disallow the permissions asked by the 3rd party apps
The API returns to the 3rd party apps.
The User can now use (or not) the application.
This implementation have 2 problems:
Every time an User ins't authenticated (cleared it's cookies, connect himself from an other computer, etc), he will have to go through the Authentication method, by being redirected to the Official website and then being redirected to the 3rd party application (the API would be transparent, since it has already allowed the application to access his data).
All those layers would certainly lost the User on the Authentication process with too many redirections.
A possible solution would be to store the user's access_token, for example in the case of a mobile app, but with a pure html/css/js oriented app, this isn't possible. A login/password in the 3rd party web application that would match the user to the access_token of the API would be an other solution, like Seesmic (I think), but this is just useless (for us, not Seesmic) : the idea of not having the user's password become useless.
This is a possible explanation but I would require more details on how this is possible and your thought about that solution. Would it work?
(I added this as an answer since it's an (incomplete and not so sure, I agree) one.