I ma using google maps in my app, and use the URL as following format without the API key- values,
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?sensor=SET_TO_TRUE_OR_FALSE">
</script>
Now I need to use the API key to track the requests, according to the examples it needs to add another API key query string parameter,
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=SET_TO_TRUE_OR_FALSE">
</script>
But, I received 2 keys,
One for servers (IP address restrictions) and one for browser apps (domain level restrictions) are as follows:
Server Key: XXXX
Browser Key: YYYYY
Which key should I use in my app, should I use both of them? Could not find a good article on this.
This is relevant again now that Google just recently deprecated Browser Keys for its Web Services APIs.
Here are the current definitions:
Server keys
Create and use a server key if your application runs on a server. Do
not use this key outside of your server code. For example, do not
embed it in a web page. To prevent quota theft, restrict your key so
that requests are only allowed from your servers' source IP addresses.
Browser keys
Create and use a browser key if your application runs on a client,
such as a web browser. To prevent your key from being used on
unauthorized sites, only allow referrals from domains you administer.
(from https://developers.google.com/console/help/new/)
Try the browser key, found this post, but it's written on 2012,
https://groups.google.com/forum/#!topic/android-gcm/Ir-dNtPRKcU
Found this on web:
"2.Click Create new Server key. Either a server key or a browser key should work. The advantage to using a server key is that it allows you to whitelist IP addresses. The following screen appears:"
http://developer.android.com/google/gcm/gs.html
Hope this will help you!
As of now (early 2018), I suspect the difference between server key and browser key is insignificant and only conceptual. Because the web console allows you to apply IP restriction or referrer restriction to any of your key. So, for the same key, you can apply a referrer restriction and then it works as a browser key, and you apply an IP restriction and then it works as a server key. Besides, I don't find specific documentation on server key vs browser key from this official help page.
Related
I have two domains
Example :
a.com and b.com
I try to implement SSO Cross-domain authentication for these two websites
I refer to this link reference How youtube gets logged in to gmail account without getting redirected? to implement like Gmail and YouTube
I have doubt about that
How to send tokens from one domain to another domain using iframe
How to pass tokens in a secure way
If I use an intermediate domain how to prevent that domain call for accessing cookies value I want to set the cookies in the second domain
Please help me to implement I searched but the sample code is not available in asp.net
have you tried this method?
Using Reverse Proxy
As #David suggested, use a reverse proxy like Nginx or HAPorxy to serve both the applications from the same domain - protocol://host:port. All three things should be equal.
Using cookies instead of LocalStorage
If you use cookies instead of LocalStorage, then host ports do not participate in determining site policy. So two application running on the same host but the different port will share cookie without any extra work. To protect the cookie, use an HTTP-only cookie, same-site cookie.
Using URL to share - IFrame only
If you are using iFrame, then you can use URL to share the token. When the outer window is loading the iFrame, send this information via hash like http://localhost:8081/somepage#token=1234
Using hash will allow the page to send data to an inner page without being sent over the wire.
Using window.postMessage - IFrame only
Using window.postMessage, you can simply pass the required data to the inner window/iFrame. As long as you control both the endpoints, you can easily do cross-domain message sending.
In the end, it really depends on your security requirements, ease-of-maintenance, etc.
The best of this is using oAuth https://oauth.net/ provides a comprehensive definition of this.
There are many open-source implementations of oAuth consumer and server available.
The concept is that a third URL will authenticate and maintain the primary session and pass tokens via URL on redirect. The consumers can utilize tokens to request the server for details directly.
Overall benifit is that you will get implementations via open-source communities in a language of your choice, and you will be able to utilise third-party logins. There are other standards you can look into as well are SAML , OpenID and LDAP and products like shibbobleth,CAS and Azure AD.
Let me clarify my use case:
I have a next.js application which is a plattform for listing real estate objects. I have several api routes which im using inside my next.js app. for example:
/api/createpost ->
Takes informations from my form on my next.js app and creates a database entry to perform a new post
/api/getposts ->
fetching all the real estate posts from my database and displays it
/api/login ->
logs in a user by checking the credentials in the database and sends a jwt
/api/register ->
registers a user by taking the credentials from a form from my next.js app, registering a user and creating an entry in my database
Now in order to secure my apis I want to make sure to check if there is a valid user session if anybody is calling one of the apis (except the register/login api) to get the expected result. Im doing this by calling the /api/login route and getting a valid user session. Until here everything just works fine. Apis like the /api/createpost can only be called if we have a valid user session.
Now I want to create a mobile app and I want to use my api routes from above to provide full functionality in my mobile app too. It should work the same, if i want to call the /api/createpost on my mobileapp for example, i need a valid user session.
But I want to restrict my api by asking for a key in my database which is pointing to my app and saying okay if you call the /api/createpost api, first of all i need to verify that its the mobile app asking. The mobile app will provide the key in the request then.
I didnt try this yet, but it should work i think. Now the big mess: If we call the /api/createpost and the api wants a valid token to check in the database, which will work for the mobile app, because we are giving it a valid token to check in the database, how can we provide a token if we are calling the api from inside our next.js application? Since I have to do the api call clientside, there is no way for me to provide a secret key or something to validate that the call is coming from my next.js application.
If your application is private
(to be used only by you or a few select people)
You can send a private API key over SSL with each request from your application to the server and verify it. Or you can limit your API to only accept requests from certain IPs.
If your application is public
Unfortunately there's no way to determine where the request is coming from, since anything your app can send, an attacker can send it manually.
Think about it, if your app is trying to make a request to your API, any user can intercept this request before its sent out of his/her machine, and send the exact same request from a different app on the same machine.
You might say, well I can encrypt the requests and responses so that they are of no use to the attacker. But such an encryption will require either a key that's already agreed upon, or some way to provide a new key at the beginning of each session.
If the key is already agreed upon, the app must contain it, as you've already guessed in the question, the attacker can retrieve this key no matter how well you try to hide it.
If the encryption key is a new key provided at the beginning of each session, that's almost how SSL works, your browser handles this transaction. Your server sends a public key to your browser to encrypt the requests which the server can then decrypt with a private key. In this case you've circled back to the same problem, how can you verify to whom you give out an encryption key? What would stop an attacker from requesting the encryption key?
There has to be some way you'd be able to design apps that don't require this restriction. I think the question you should be asking isn't how to restrict your api to a certain app, but how to design apps that don't require this restriction.
We might be able to help you out if you could tell us why you need this restriction.
Update
There is actually a way to verify that requests are coming from your app, but not with an api key.
For Webapps
You can use Google's reCAPTCHA to verify a user on your /register and '/login` routes, and provide an access token or start a valid user session on successful captcha response. With reCAPTCHA v3, you could even verify every user action without interrupting the user. This eliminates both the problems I mentioned in my answer above -
You don't have to store an api key into the app/web app.
The request can't be spoofed as it requires human user interaction within your app. The captcha verification success will arrive to your API from Google's reCAPTCHA server, not from your client app. This communication will be authenticated with a pre-mediated private API key shared by Google to you, which works in the same way as to how you authenticate your external domains.
For Android apps
A similar way to achieve the same thing would be via Android SafetyNet Attestation API. This checks the runtime environment and signs the response with a dynamically generated nonce that your app provides the SafetyNet API.
Please read its docs carefully to understand how you could create potential security loopholes and how to avoid them while using this API.
For iOS apps
DeviceCheck works in a similar way, except the device validity is provided to you by Apple server.
Important edit: "secured" is not the right word here! You cannot tell that a request comes from your app just because the domain is yours. The domain name is not a safe information, as it can be altered easily. See #Mythos comments below.
Initial answer:
Web applications access is secured not based on an API key, but based on a whitelist of domains. That's how we achieve security, because only you have access to the domain where you host your own application: so the request has to be coming from an app you own.
If you try some 3rd party services that provides API for web apps, that's often how they'll work: they will let you configure a set of whitelisted domains that can access your data.
If they provide you an API key, this API key is always meant to be used by a server, not a client-only app.
So if I understand you question correctly, you would do like this for each request:
Check the domain. If it's in the whitelist, perfect, you can keep going. This is meant for web apps (look for "CORS").
If not, check for a valid API token in the headers. This is meant for any app that can store this API token securely (another server for instance, or a mobile app in your scenario though I don't know mobile enough to tell how you store such a key)
How can I limit the access to the Google Translation API to only a specific IP, the IP of my server? Because someone else is using my API and I hit the limit of requests frequently
The authentication to Translation API can be done with two main methods:
Using a service account: the service account key can be downloaded as a JSON file, and only the people who own that file will be able to authorize their requests against your API.
Using an API key: it is a simple encrypted string that can be used for authentication when calling certain Google Cloud APIs. When using this method, you should follow the best practices, which include the method you ask for in your question, restricting API key usage by IP address. You can do that following the guide in this documentation page, which consists in:
Go to the Credentials page inside the APIs & Services tab in your Console.
Select the Create credentials drop-down menu and then on API key.
In the pop up menu that will appear, click on Restrict key.
Choose the IP addresses option and type the IP address you want to allow. Then save.
Then you will be able to use that API key as a secure method for accepting requests only from your server.
How to prevent someone just taking my API keys from the client side javascript code and starting to use my HERE subscription for some other use.
I noticed HERE provide an option to secure the API keys for a certain domain on the applications management page: "Secure app credentials against a specific domain". I have set up this option and also put domain there but I do not see any change on my app behavior.
The application still continue working fine on my PC. Shouldn't the HERE API stop working as web server is running on localhost and not on the defined domain.
My app is running fully on browser, and only static files come from the server (http://localhost:8083/index.html). I am using the HERE javascript API.
I tested also running the app on external cloud service on different domain than localhost. Results are the same. My conclusion is that the setting "Secure app credentials against a specific domain" just has no impact and does not work. Checked also the api response headers and all origins are accepted.
Access-Control-Allow-Origin: *
In your HERE dashboard, you can set the application id and application code to only work on a particular domain or set of domains. If the tokens are fixed to a domain, it won't matter if someone takes your tokens because only the listed domains can use them. If you don't secure the tokens to a domain, then someone will be able to use your tokens if they find them.
I'd like to use Google Identity Toolkit API to identify the user of a web site.
I made the example program without problems, but when trying to push it on a remote web server it does not work.
I made a new project (so I have new credentials for server, client and apikey).
I made all the modification to the PHP and JSON file but when I try to login I get : There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed
I don't understand where referer are specified because the aipkey is auto generated when you change the API configuration and in API configuration there are not referers or ip indication.
Where am I doing wrong?
Go to google developers console.
Select the project you previously created and then go to Credentials option in the APIs & auth menu on the left.
Under API keys, select browser key. You can configure the browser key referrer there.
Under api key there was only one key automatically created by the api configuration.
This key had no name and i can't find a way to modify or view it.
I tried to delete it several times, but every time was created without name.
I tried to add a new key by myself, but that key wasn't accepted.
I had to delete the auto generated key, create a new one, and then go modifying the api config.
Then it worked....