I have a question regarding implementing Google speech, or google cloud API in general, for Android
What I want is to have multiple certificates or API keys for different clients.
In practice, I can have 10 different Android devices, linked to Server 1 for Client 1, and 20 different Android devices, linked to another server for Client 2.
I would like to split the billing of this clients but using same Android project/package.
In https://github.com/GoogleCloudPlatform/android-docs-samples/tree/master/speech/Speech example there is an OAuth2 Credential used, but the problem here is that you can have only 1 OAuth2 Credential for 1 project, but in this case I would need multiple, so this is not an option.
Even if I implement OAuth2 on a server and refresh Tokens for devices, I would need to have multiples.
In the end I would have 1 google account, with multiple client configuration, where each client is seperate when checking billing info and also for restricting purposes. If I have multiple keys I can just disable one and that is
So my question is (if I can split billing for specific API key/service account, or just know the usage used)
How to change example implementation to use API keys or different Service accounts with GoogleCredentials.fromstream()? Do I need to manually implement API requests to google REST API, or is this possible in Android with something like:
SpeechClient.create(SpeechSettings.newBuilder().setCredentialsProvider {API_KEY}.build())
You can't have billing details per API Keys used on Speech API. Here, the easiest solution is to have one project per customer. When a request come in, check the user Id (because the user is already authenticated and you have a OAuth2 token) on the server and, according with the user info stored somewhere (we use Firestore for user profile storage), call the Speech API in the correct project.
You have 1 billing per project, and a free tier per project also!
Edit 1
It's possible I wasn't clear. Here a schema.
Related
I'm making an Android app that uses the Google Calendar API with a group of 3 other students, and we're struggling to understand the authentication process.
We expected to be able to be able to just include a Java library that calls the API and set our app to request calendar permissions, and then sign in to our personal Google accounts on our emulators and have the app be able to access our respective Calendars. We kept getting 403 (forbidden) errors, so obviously that didn't work.
So we tried to stumble through the confusing API documentation and copied some things from the Quickstart project. We managed to share the project with each other on the Google Developer Console and add OAuth credentials for each of our computers, and now it works for each of us, but we're still confused.
Why is this credential creation necessary?
How will the release process work? Obviously we don't want our users to have to generate SHA1 keys per-device to use our app from the Play Store.
Is there an easier way to do this? Do we even need the Developer Console?
These questions have likely already been answered, but I don't know enough about the process to know what to search for.
Google uses OAuth 2.0 for user authentication. What it means is that whenever a third party app requires permission to access Google's data, user has to first approve that request.
Now, to provide authorization Google provides you credentials (key & secret),Using this key & secret Google generates Access key and Refresh key to the application.
Access Key: Key used to access data from Google server for limited time.
Refresh Key: Key used to fetch new access key when older one expires.
Now focusing on your questions.
Q: Why is this credential creation necessary?
A: Credentials to assure that only your app can access user's calender data.
Q: How will the release process work? Obviously we don't want our users to have to generate SHA1 keys per-device to use our app from the Play Store.
A: Google will generate access and refresh key.
Q: Is there an easier way to do this? Do we even need the Developer Console?
A: Trust me..once you figure it out,it is very easy and most importantly secure way. (Google does not allow authentication using password as default)
You can learn more from here: https://developers.google.com/identity/protocols/OAuth2
I'd like to use SSO (Single Sign-On) for users of my app, but I don't understand how to apply it to my case.
To summarize, we have:
a database
a website
an iPhone app / an Android App
Currently, it's possible to create an account on the site, and then use the same credentials to connect from the mobile apps. All communications between mobile apps and server work through http requests.
To put it simply, I would firstly
be able to use Google accounts to authenticate users
offering Android users to choose one of Google accounts associated with their smartphone
I found several sources of information:
Google - Using OAuth 2.0 for Login
Android - Remembering Users
Unlike what I saw in some examples, I don't need to make request to Google services like Google Calendar or Tasks, I just want to authenticate the user.
Does someone could tell me what I need to do on the website and on the mobile app. Should I store information in my database? How to ensure that after authentication, all http requests from the mobile application are really from authenticated user?
Do not hesitate to ask me to clarify some points.
Thanks in advance
As OAuth is a standard for authorization and not for authentication, it doesn't support any direct method for this. However, most providers allow you to call an endpoint that returns the id of the logged in user. Google returns the id as part of the basic profile information. This step is described in the first article you already mentioned. There are multiple libraries available to simplify this step for you.
So for identifying a user you acquire his Google user id and store/match it in your database.
To get the user's id on an Android device, there's an even more simple way. Just use Google Play Services as described in its documentation. You can find the user id in the response to the call in the last section of the documentation.
Now there's still the problem that you have to send the user id from the device to your web server and verify that this call was issued by your app. Fortunately, Google has also built a method into Google Play Services for exactly this scenario. There's a blog post by Tim Bray at the Android Developers Blog about this.
I have gone through the Android documentation and other blogs related to using the Places API in an Android application. Everywhere it suggests to use the API_KEY to call the REST service. The API_KEY being the same throughout the project/application. There is a limitation of 1000 requests per day.
Now if my application is installed by many users, then the request limit will be easily exhausted if the same key is used by everyone.
There would be some way to generate the API_KEY for individual user. But how can I take care of it in my code?
You can have the quota raised to 100,000 requests a day if you verify your identity:
Users who have verified their identity through the APIs console are
allowed 100 000 requests per 24 hour period. A credit card is required
for verification, by enabling billing in the console. We ask for your
credit card purely to validate your identity. Your card will not be
charged for use of the Places API.
You'll find this information and more if you go to the Google APIs Console, select Services and click on the Pricing link on the Places API line.
100,000 requests a day is a lot and should be sufficient unless your app is extremely popular. And I don't think that creating several user to generate several API keys will be possible without violating Google's terms and policies.
The Story: I am making an Android app that allows a user to purchase a subscription, and does not require the user to have an account or login. I want to check whether or not a user has purchased a subscription, and the Google Play Android Developer API seems to provide this service.
The Problem (TL;DR): Should I use OAuth as a "web application", "installed application", "service application", or none of the above?
The Problem: To get started with this, I am told:
Access to the Google Play Android Developer API is authenticated using
the OAuth 2.0 Web Server flow. Before you can use the API, you will
need to set up an APIs Console project, create a client ID and
generate a refresh token. -source
Fair enough. There are then setup instructions that go on to say:
On the second page, select web application and set the redirect URI
and Javascript origins.
My application does access the Internet, but it is an installed Android app, not a web application, so I don't have a "redirect URI" or "Javascript origins" to link it to. Additionally, this would require a user to log in, which I do not want and is not necessary in my case (I just want to check whether or not the user has purchased a subscription).
So if instead of a "web application" I try to create an "installed application (Android)", this still requires a user login, to be able to manage the user's resources.
I do not want this. There is a third alternative called a "service account" that does not require a user login:
A Service Account is used when you have a service that wants to handle
its "own" resources (e.g., an App Engine app that manages Compute
Engine resources), as opposed to the resources of an external user
(e.g., the standard OAuth flow). Using a Service Account the app will
be the owner of the resources... If you use a Service Account, you will only get data about the service's purchases. -source
I'm not sure if that is what I want in my case...
Finally, there is also this option:
The simplest flow is one where no end-user authorization is needed.
You still need to identify your client application using the API key. -source
This seems perfect! However, I was told initially that to use the Google Play Android Developer API I need to authenticate with OAuth 2.0, and this does not use a client ID which I was initially told that I specifically need.
There are at least 2 problems with what you are trying to achieve here:
As you would be handling the server response in your Android application, you would have something like this in your code:
if (isSubscriptionValid())
Somebody could tamper with your application's APK on his device (which is very easy) and simply replace that check with:
if (true)
The attacker would then have access to your content without ever being subscribed.
As calls to the API have to be authorized by your developer account and being personally logged in on each users device is obviously no option, you would have to go for Service Accounts, as you've already figured out correctly.
These however are only meant for server-to-server interactions, as otherwise it would require you to store your private key on everybodys device and as it is not possible to store data securely on an Android device, you wouldn't meet this requirement:
The private key must be stored and managed securely.
Google recommends you to have a backend server to do this kind of checks. So you can decide if a subscription is valid before handing over content to the client and other things:
The API is designed to be used from your backend servers as a way of securely managing subscriptions, as well as extending and integrating subscriptions with other services.
If you do not have a backend server available, you have to rely on In-app Billing Notifications.
I am using Android Licensing as described here:
http://developer.android.com/guide/market/licensing/index.html
(...to verify that my customers for my android app have actually payed for the app.) My app has a server component on the web, and for extra safety I'm doing the license validation on this server.
It all works okay. Now, to my problem. Since each new user ties up resources on my central server, I'm actually kind of reluctant to have non-paying users. I have seen some evidence of users continuing to use the app after having gotten a refund (per the normal 15-minute grace period).
To curb this behavior, it would be great if there was some way to map the payment of users at Google Checkout, to actual users in my system. Is this possible?
The ResponseData that I receive from the android license server contains a field called "userId", but this doesn't seem to correspond to any information in Google Checkout. (See http://www.androidadb.com/source/skylight1-read-only/GoogleLVL/src/com/android/vending/licensing/ResponseData.java.html for the definition of ResponseData.)
Is it possible to determine which payment in Checkout maps to which app installation?
As I currently understand it, the userId is obfuscated even on a per-app basis such that you can uniquely identify users per app but not figure which user it is nor whether the same user bought another app.
But I'm not sure you really need to identify these customers based on userId. If you have a server running anyway, the best way to protect your app is to have your server check the licence.
App -> Server: Give me a new nonce
Server -> App: Here is a secure random nonce
App -> Licence Service: Check user licence with this secure random nonce
Licence Service -> App: Signed licence response including repetition of nonce
App -> Server: Check licence signature with secret key (only on server)
Server -> App: Reject, or provide random token for access, etc
In this scenario, you won't authenticate users even if they mess with your LVL checking code.
However, you may of course introduce vulnerabilities after step 6 if you don't watch your step. Still, if you're currently using the standard LVL code and App-side licence check with the secret key stored in your app, changing to a mechanism as sketched above would be a huge improvement (there's even a script to remove standard LVL checking code from apps).