I am working on a mobile project that is built on ionic and uses Firebase for auth, database, storage, etc. A few days ago, I applied restriction to the Firebase api keys on Google Cloud Console by setting up HTTP referrer for iOS/Android/Web api keys.
Problem is - both iOS and android builds are having issue with Firebase api calls (web app still works normally), throwing the following error:
[ Requests from referer <empty> are blocked. ]"
!! smsLogin ERROR"Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., NSUnderlyingError=0x282938ff0 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={FIRAuthErrorUserInfoDeserializedResponseKey={\n code = 403;\n details = (\n {\n "#type" = "type.googleapis.com/google.rpc.ErrorInfo";\n domain = "googleapis.com";\n metadata = {\n consumer = "projects/770668602613";\n service = "identitytoolkit.googleapis.com";\n };\n reason = "API_KEY_HTTP_REFERRER_BLOCKED";\n }\n );\n errors = (\n {\n domain = global;\n message = "Requests from referer are blocked.";\n reason = forbidden;\n }\n );\n message = "Requests from referer are blocked.";\n status = "PERMISSION_DENIED";\n}}}}"
What does the referrer <empty> mean here?
This error message means that the HTTP "Referer" header field is either completely missing or having a blank value in the HTTP request being sent to underlying Firebase or any other Google Cloud API. HTTP Referer header field allows identification of the web URL (page) that is requesting access to a resource (such as an API). This identification enables implementation of API Key Restriction control using HTTP Referrers as described here.
Since you have mentioned in the problem statement that only iOS and android builds are having issues with Firebase api calls but the web app is still working normally, it looks like the issue is that the HTTP "Referer" Header (optional) field is not being set in your Android & iOS apps.
For web applications using browsers, HTTP "Referer" field is set automatically by the browser which is why the web app did not exhibit this issue in the first place. A similar issue is nicely answered & described on this other StackOverflow question.
Related
I have an android app with a python server. I need the server to have access to the users' emails constantly, so I'm following this guide:
https://developers.google.com/identity/sign-in/android/offline-access
def google_api(auth_token):
# If this request does not have X-Requested-With header, this could be a CSRF
#if not request.headers.get('X-Requested-With'):
#abort(403)
# Set path to the Web application client_secret_*.json file you downloaded from the
# Google API Console: https://console.developers.google.com/apis/credentials
CLIENT_SECRET_FILE = 'secret.json'
# Exchange auth code for access token, refresh token, and ID token
credentials = client.credentials_from_clientsecrets_and_code(
CLIENT_SECRET_FILE,
['https://www.googleapis.com/auth/gmail.readonly', 'profile', 'email'],
auth_token)
print credentials
return credentials.id_token
I get the following error:
FlowExchangeError: redirect_uri_mismatch
Here is the secret.json:
{"web":{"client_id":"REDACTED",
"project_id":"REDACTED",
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"REDACTED",
"redirect_uris":["http://localhost:8080/"],
"javascript_origins":["http://localhost:8080"]}}
I've also tried using http://my_actual_domain.com:5000/ for the redirect_uris and it still returns the same error.
I don't understand what redirect_uris is supposed to be or mean? It's not mentioned in the guide I link at the top
Redirect uri is something which you give it when you created OAuth Client ID. The one you used in the application should match the one you gave while requesting the Client ID.
Please make sure this configured properly.
I currently have a login flow with facebook that is working 100% and I just added Google into the equation. I wrote the code so that my google provider tokens are formatted and cached in the same way as my facebook tokens. My code gets the facebook and google tokens and does the folling: (the following example is for the google login):
USER_GOOGLE_TOKEN = new JsonObject();
USER_GOOGLE_TOKEN.addProperty("access_token", accessToken);
cacheProviderToken(USER_GOOGLE_TOKEN.toString());
setCurrentProvider("google");
Then, in my authentication method in the activity, here is how I mobileserviceclient.login:
MobileServiceAuthenticationProvider provider = null;
if (getCurrentProvider().equals("facebook")){
provider = MobileServiceAuthenticationProvider.Facebook;
} else if (getCurrentProvider().equals("google")) {
provider = MobileServiceAuthenticationProvider.Google;
}
token.addProperty("access_token", googleToken);
ListenableFuture<MobileServiceUser> mLogin = mClient.login(MobileServiceAuthenticationProvider.Google, getProviderToken());
The problem is that Facebook works and Google produces a 401 unauthorized.
The specific error I get (before the future returns failed), is: W/DefaultRequestDirector: `Authentication error: Unable to respond to any of these challenges: {}. Azure logs show that it is a 401 unauthorized.
I am successfully printing the Google-Sign-In token and formatting it in the same way as my facebook tokens before trying to use them. Are my google keys wrong? I regenerated them once already and I tried setting origions to https, I tried different key combos, and I even got rid of my google-services.json(apparently its not needed). I did not use the client key that was generated on this google doc.
Another question here is how does the authentication settings of my Azure Mobile App come into play? I had originally configured my facebook before migrating from a MobileService to MobileApp, and now I do not need to use the "turnkey authentication" feature for it to work. I went ahead and entered my app key and secret for facebook, but it definitely works regardless of whether or not this is enabled. Is this a necessary feature for oauth?
Also, Depending on the token format on Login and the On/Off status of the AUthentication feature, the errror: W/DefaultRequestDirector: Authentication error: Unable to respond to any of these challenges: {}
, will have some text in the curly brackets about the azure endpoint.
Thank you so much if you can help. Such a picky issue here.
The App Service Authentication / Authorization is incompatible with a migrated Mobile Service and must remain off.
To update Authentication settings with a migrated Mobile Service, you set the app settings. For facebook, that's MS_FacebookAppID and MS_FacebookAppSecret. For Google, that's MS_GoogleClientID and MS_GoogleClientSecret.
For reference, check out https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-migrating-from-mobile-services/#authentication
I am attempting to implement a GCM-enabled Android application but I am having trouble authenticating with the CCS server from my 3rd-party-server.
import sleekxmpp as xmpp
SERVER = 'gcm.googleapis.com'
PORT = 5235
USERNAME = 'my-project-number'
PASSWORD = 'my-api-key'
def main():
client = xmpp.ClientXMPP(USERNAME + '#' + SERVER, PASSWORD)
if client.connect(address=(SERVER, PORT), use_ssl=True):
print('Connection established.')
print('Authenticated =', client.authenticated)
else:
print('Connection failed.')
if __name__ == "__main__":
main()
Output:
Connection established.
Authenticated = False
Process finished with exit code 0
Not sure as to why client.authenticated is always false when I know the credentials I have are the same ones on the project page in the Google Developer Console.
Since you haven't really supplied a specific error message from the logs I will post a quick troubleshoot here. I used it myself when I had problems.
Server Ip
Server IP: you have correctly set the IP of your 3rd party server in the console. It's where you configure the API key, so I bet this is ok.
Whitelisting
When you want to try out your project over xmpp you have to get it whitelisted, this is not so clear when reading the developer docs from google. Refer to this question for more explanation: Google CCS (GCM) - project not whitelisted . The link to get in line for whitelisting: https://services.google.com/fb/forms/gcm/
Http
If the above also did not grant results you might want to check out if everything works fine using HTTP json messages, for which your project does not has to be whitelisted. Since this method has been around for some time, there are some working libraries like this one: https://bitbucket.org/sardarnl/gcm-client
I've been having problems implementing Google Play Services login on my android app and passing the authorisation code to my backend server, so the server will exchange the code for access token and refresh token.
First let me write a few lines what has already been tried/read:
on code.google.com/apis/console I've created a new project, with two clients (WEB client and Android installed client)
read articles on https://developers.google.com/+/mobile/android/sign-in#cross-platform_single_sign_on and http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html
Next I wrote simple android app (based on Google Play Services sample auth app) and a simple python code using gdata (using web service client_id and secret).
On android app I first used four scopes delimited with space and got a token. If I use this token in my python code I always get {'error_message': 'unauthorized_client'}.
Then I tried to change the scope to this values and always got invalid scope error.
oauth2:server:client_id:server-client-id:api_scope:scope1 scope2
audience:server:client_id:server-client-id:api_scope:scope1 scope2
oauth2:audience:server:client_id:server-client-id:api_scope:scope1 scope2
For server-client-id I used the client_id of web server client, android client, other client
Please can anyone help me with this problem.
Thanx
Here is the code for python backend
import gdata
import gdata.gauth
CLIENT_ID = 'client_id'
CLIENT_SECRET = 'secret_id'
SCOPES = ["https://www.google.com/m8/feeds", "https://mail.google.com", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"]
USER_AGENT = 'my-app'
token = gdata.gauth.OAuth2Token(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scope=' '.join(SCOPES), user_agent=USER_AGENT)
print "token ", token
print token.generate_authorize_url(redirect_url='urn:ietf:wg:oauth:2.0:oob')
try:
print token.get_access_token("token")
except Exception, e:
print e
print e.__dict__
You are retrieving an authorization code, not an access token. These are two different things.
Authorization codes can be used in your server side to get an access token. They are not access tokens and cannot be used as such.
I got the google cloud endpoints working with an android app and backend written in python app engine. When I uninstalled and re-installed my app during development, I started running into a 401 error from the backend. This is without any changes in backend after I got it to work the first time. So,
I cleaned up debug.keystore file in C:\Users\username\.android and
also other files in the same directory.Regenerated the
debug.keystore file again and got the new sha1 footprint
Deleted the API project in google apps console and regenerated web
client_id & android client_id with new sha1 footprint
Used the new web client_id and android client_id in server side code
Also updated the android cliend_id in audience scope in android code
After I installed the app now, still see the same 401 error. My app engine logs show this,
I 2013-04-07 16:45:27.297 Checking for id_token.
W 2013-04-07 16:45:27.299 id_token verification failed: Invalid token signature: eyJhbGciOiJSUzI1NiIsImtpZCI6IjMzMTJkNDc0ZWUzNWRjNWU4YzFhMDE4OTkzOGZkN2E3YmUzYmRlZjYifQ.eyJpc3Mi
I 2013-04-07 16:45:27.299 Checking for oauth token.
I was able to gather more information based on Cloud endpoints oauth2 error and http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html,
I decoded the id_token being sent to the app_engine server and found that it has these fields,
cid = Android app client_id that I registered in app console for
azp = Android app client_id
aud = web client_id for App engine
iss = accounts.google.com
verified_email = true
email_verified = true
email = account i selected in account picker in android app
exp = a datetime having a value in the future
first_segment = {u'alg': u'RS256', u'kid': u'3312d474ee35dc5e8c1a0189938fd7a7be3bdef6'}
Above values seem right, but id_verification fails. Not sure why.
Had the issue again. Happens, when I reinstall my app after uninstalling. Cloudend points service threw invalid token error. Used the token and verified it using the url. Get an output like below which means the token is valid.
"issuer": "accounts.google.com",
"issued_to": "172895167251-1prp5r093hf2nro5bei2cmc1tqf4aasdu.apps.googleusercontent.com",
"audience": "172895167251.apps.googleusercontent.com",
"user_id": "myuserid",
"expires_in": 3086,
"issued_at": 1365644284,
"email": "emailIselectedinadroidapp",
"verified_email": true
Interesting. What happens if you send the id_token to tokeninfo endpoint?:
https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=$id_token