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
Related
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.
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 am developing an Android SIP client. I'd like to test it against OfficeSip server. So I have set up the officeSip server locally and I can connect to it via officeSIP messenger (the client).
The messenger requires this data to login:
List item
addr: username#server_domain
username: username
password: password
protocol: protocol
server address: server address
However, when trying to do the same in Android, its SipProfile.Builder has a bit different parameters. Of note are the following:
public SipProfile.Builder (String username, String serverDomain)
public SipProfile.Builder setOutboundProxy (String outboundProxy)
There doesn't seem to be a server address available.
I have tried the following for serverDomain parameter:
user#server_domain/server_ip
server_domain/server_ip
server_domain#server_ip
many other combinations
However, I'm either getting connection error (when # is used) or registration failed event (when / is used with server IP after the /). Error codes are -4 (When some error occurs on the device, possibly due to a bug) first, immediately followed by -9 (The client is in a transaction and cannot initiate a new one)
How can I connect to OfficeSIP using Android SIP client?
Edit:
I managed to establish communication with CSipSimpleClient which uses a custom SIP stack. It only required server name (equal to server's domain), username and password.
I'm not sure.. but '#' and '/' are not allowed and SipProfile.Builder will make a URI, e.g. "username#serverDomain(or ip)", with username and serverDomain parameters.
Just try to set like this.. ("user1", "test.com"), ("user1", "1.1.1.1").
API description says "the SIP server domain; if the network address is different from the domain, use setOutboundProxy(String) to set server address" about serverDomain.
Turns out, Android SIP stack is quite immature and finnicky.
Ultimately I was able to connect by specifying both server hostname and server proxy.
Also, if server domain differs from computer name server is running on, you WILL have issues connecting. Domain must match either IP address or computer name, but they must match in order to connect via Android SIP client.
I have successfully connected to OfficeSIP with the android SIP API.
Download the SipDemo here
In WalkieTalkieActivity.java I modified the code to be the following:
SipProfile.Builder builder = new SipProfile.Builder("test", "officesip.local");
builder.setPassword("test");
builder.setOutboundProxy("192.168.10.191");
builder.setAutoRegistration(true);
me = builder.build();
In OfficeSIP test is the user with a password also test. The outbound proxy is the IP of the computer or server hosting OfficeSIP and officesip.local is the SIP domain name, which can be found in OfficeSIP under ther settings tab.
To test this I made a second account on OfficeSIP and logged into that account using Sipdroid. From there I called the SipDemo app running on a second phone and it worked.
I am attempting to run gcm server using node-xmpp, but xmpp client does not seem to open at all and closes after timeout.
var xmpp = require('node-xmpp-client');
var options = {
type: 'client',
jid: 'fake-project-123#gcm.googleapis.com',
password: 'ApiKeyHere',
port: 5235,
host: 'gcm.googleapis.com',
legacySSL: true,
preferredSaslMechanism : 'PLAIN'
};
console.log("Creating XMPP Application");
var cl = new xmpp.Client(options);
cl.on('online', function()
{
console.log("XMPP Online");
});
Rest of the code was omitted. In the console, I never get to see "XMPP Online".
How do I check if xmpp is even connecting, and where it fails to open?
I got the same problem and found out that the Connection.startStream() was never called, although the socket was opened successfully.
Here's my pull request:
https://github.com/node-xmpp/node-xmpp-client/pull/61
Until it gets merged, you can use my fork, which should work for GCM:
https://github.com/Riplexus/node-xmpp-client
I followed this from gcm google groups and it worked for me.
And for timeouts you can try
xmppClient.connection.socket.setTimeout(0)
xmppClient.connection.socket.setKeepAlive(true, 10000)
Don't forget to whitelist your server ip in google console.
I have given up the hope of using node-xmpp and game smack client a try. Sadly it did not work, but I did get an error saying my project is not whitelisted. When project is whitelisted, it can receive messages from android devices, which is exactly what I need and is the sole reason why I went straight to CCS (XMPP). Without the whitelist, it is not possible to use CCS (XMPP) for sending the messages to android devices. In order to use HTTP method, the project does not need to be whitelisted, but has a limitation to being able to send messages only. I have signed up upstream GCM but have yet to receive response.
https://services.google.com/fb/forms/gcm/
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.