We are developing a system where the client (mobile app) communicates with mostly with a node.js backend and sometimes with firebase directly.
One of the features is peer to peer messaging and we are using ChatSDK on the client side to integrate Firebase. We are having some difficulties understanding custom authentication with ChatSDK.
What we want is a user to be able to register and sign in (Email,Facebook, Google) using the ChatSDK. Our backend authenticates client calls using admin sdk’s verifyToken function. The token expires every hour - should client be grabbing a new token every hour? How does the refresh token come into play here?
We do have an endpoint on our server which can generate a custom token using createCustomToken(uid) function. Should the user first register with the chatSDK then use this endpoint to grab the token? Is this a security concern that all someone needs is a user’s id to grab a token to access sensitive data through HTTP endpoints?
1) How can we grab Token from the chatSDK alone?
2) How does a user ensure it always has a valid token to communicate with node.js backend?
Related
TL;DR - How can I refresh tokens backend-side if the oauth2 authorization happens in native android/ios app?
I am working on oauth2 integration with google calendar. My stack is react SPA app as web client and we have a backend API (in elixir). We are also using hybrid native apps, so our JS code is transformed into corresponding iOS/Android apps (using capacitor).
The flow is as follows:
user authorizes us to modify their calendars using oauth2, we ask for offline access
we acquire client-side authorization code from google
we send it to our backend and it uses the auth code to acquire access token and refresh token, the tokens are then persisted in our DB
we use the access token to perform updates to google calendar. When token expires we refresh it backend-side
This is the flow that is working on the web client, but with native apps (android/ios) I am stuck. When I use corresponding to ios/android apps clientIds from google console project credentials, my backend cannot successfully use it to acquire refresh and access tokens, I get the following response from https://oauth2.googleapis.com/token:
%{"error" => "invalid_client", "error_description" => "Unauthorized"}
I am considering moving the process of exchanging authorization code to refresh token and access token to the native apps, but how can the backend then have access to new access tokens? I can't refresh the tokens backend side if they were generated in the native app, I will again have clientId mismatch (also backend uses clientSecret, while native apps are exempt from using clientSecret).
You cant. The refresh token is client id based. You need the client id and client secret that were used to create it in order to refresh it.
The client used for Ios and android apps doesn't have a client id and secret that you could use backend.
You can do it the other way around though. If you created the refresh token in your backend app. The ios and android apps could refresh it as long as the client id is part of the same project.
I suspect there is something internal in the android and ios sdk's that allow for this. It just doesn't work with any other type of client due to the lack of client secret.
take a look at this documentation, it works form me in the same problem.
https://developers.google.com/identity/sign-in/ios/offline-access
"On your app's backend server, exchange the auth code for access and refresh tokens. Use the access token to call Google APIs on behalf of the user and, optionally, store the refresh token to acquire a new access token when the access token expires."
serverAuthCode is used on this api https://developers.google.com/identity/protocols/oauth2/native-app#exchange-authorization-code to generate a new refresh_token
I had the same issue and finally ended up.
In order to design user authentication from the mobile/front-end side and send the authorization code to the server-side to exchange it for access_token and referesh_token you have not to follow the Mobile or Installed App flow:
In this way, you've created Android app OAuth2 credentials in the google developer console and used its client_id for google oauth2 page preparation so at the end you will have access_token which works only on the mobile side and does not work on the backend as it doesn't have client_secret.
Therefore, if you want to have access to the google APIs on your server-side and just perform the google authentication on the mobile side you can choose one of the following flows:
As you can see from the above flows, there are three parts namely client-side (mobile), google, and server-side (backend) rather than communication just between mobile and google which is useful for installed applications, not web applications. To me, between these two flows, I prefer the last one as it has fewer requests to create access_token and refresh_token on the server-side.
Here's the whole procedure:
create a web application oauth2 credentials on the google developer console and use all sections in the backend and the client_id on the mobile side as well. Don't forget to enable the API you want to use.
create a /callback endpoint in the backend which is the same as redirect_uri that you will need on the mobile side. In this endpoint, you will get the authorization code from the google request and then exchange it to the access_token and referesh_token and persist that on the DB.
create an endpoint in order to call google API such as google calendar.
Bring up the google authorization page on the mobile using SDKs, web view, or browser with the following content: existing client_it (which is the same with server-side), redirect_uri (callback), response_type="code", scope="https://www.googleapis.com/auth/calendar", access_type="offline", include_granted_scopes=true, and state to put some string if you want, for example I sent user's uuid.
You can obtain access_token using refresh token by sending
POST https://oauth2.googleapis.com/token
x-www-form-urlencoded
client_id:CLIENTID
refresh_token:REFRESHTOKEN
grant_type:refresh_token
I have the following situation:
I have an app that will be using a subscription based payment system via the app or play store. I want to avoid implementing my own account system and verify the users via the Apple-ID or what the equivalent is on Android side, using Apple/Google Sign-in if this is possible.
The problem is that the app will have to communicate with a server every week, so that means the requests to the server need to be authenticated, that this is coming from a client (smartphone/tablet) that has an active subscription going. How do i do this the best way?
If i understand correctly then using Apple Sign-in you will get a token. Should i send this token to the server, where the server then communicates with the App Store API to verify the token on every request? Is this completely equivalent on the Android/Play store side? Or should i verify the token once on the first request, then generate my own token and send it to the client so for the rest of the session it can authenticate using that token to avoid having to go to a third party system on every call. But how do i store this self-generated token? As it needs to be linked to something on the client. Am i legally allowed to store Apple-IDs on a server?
I have an ASP.Net Core 3.1 web-api application that uses MS Identity framework to generate JWT tokens for the logged in user.
Then I have a client application (html , javascript) that connects to that web-api.
I also have an android application that connects to the same web-api application.
I want to log out a user from web client when it logins from the android application.
How to do that?
This is the challenge with JWT token. TO validate JWT token client doesn't need to talk to token issuer. If the client does then no use of using a JWT token.
You can follow the below approach to handle logoff scenario:
Approach 1) Keep JWT token a very short life span.
Approach 2) Maintain a distributed cache - where all the logged off JWT token can be stored and before validating the token check with the distributed cache.
I see some similar questions related to this question but those ones are too old to be considered, so I will ask again here.
I have an Android App that needs to authenticate to a web service to exchange data that will be stored on Google App Engine. For that, I would like to use OAuth2.0 to provide an authentication mechanism between my App and the web service as shown here: https://developers.google.com/identity/protocols/OAuth2WebServer?hl=en and here https://developers.google.com/identity/protocols/CrossClientAuth
I'm already doing a validation of the token on the web service side as shown on the documentation. The only part that I don't have clear is what to do on the GAE web service and Android after a refresh token is being obtained on Android and validated on the web service.
The questions are:
Must I exchange this token all the time for every communication
between the app and the web service? is it secure?
What is the best way to keep the communications going forward?
After researching about this, this authentication flow I'm using:
Sign in on the app as shown here: https://developers.google.com/identity/sign-in/android/sign-in
After Sign in, obtain a token.
Send the token over HTTPS to backend server
Validate the token on backend server with GoogleIdTokenVerifier verifier (you can also call the tokeninfo endpoint) as shown here: https://developers.google.com/identity/sign-in/android/backend-auth
When you receive the Token on your backend server you should:
After you receive the ID token by HTTPS POST, you must verify the integrity of the token. To verify that the token is valid, ensure that the following criteria are satisfied:
The ID token is a JWT that is properly signed with an appropriate Google public key (available in JWK or PEM format).
The value of aud in the ID token is equal to one of your app's client IDs. This check is necessary to prevent ID tokens issued to a malicious app being used to access data about the same user on your app's backend server.
The value of iss in the ID token is equal to accounts.google.com or https://accounts.google.com.
The expiry time (exp) of the ID token has not passed.
If your authentication request specified a hosted domain, the ID token has a hd claim that matches your Google Apps hosted domain.
User authenticated. Token must be sent over on the request header for every communication with the backend server, then the backend server needs to verify it everytime.
I'm using Google+ authentication in my app to allow a user to sign in, and have access to their 'data' on my server.
The authentication process following the following steps:
User logs in using Google+ on the app, and receives an access token.
The user passes this token to the server.
The server uses this token to verify that the user is who they say they are (following the process shown here). The server can return the data as needed.
This is the part I'm stuck on - How do I verify that the user is who they say they are for future requests without making a request to Google's servers every time? Do I return a session token to the client application that is used, and regenerate the token after some amount of time?
Absolutely. Sending a session cookie is exactly the thing to do.
You will want to use ID tokens to verify that the user is who they say they are. There is a sample project in Java on Github to demonstrate this.
Also, you should be passing a one-time authorization code to your server, not access tokens. See the documentation for getting your server side tokens from an Android app. When you have that code, you send that to your backend and then exchange that one-time code for the server's own copies of access and refresh tokens for that user. Because you receive the tokens directly from Google on your backend they are more secure than having to send between mobile apps and your backend.