I am currently at a loss on how to proceed with my app.
I currently authenticate following the tutorial here and everything works swimmingly.Azure Mobile Apps Authentication
Where I am at a loss is how to use the id and/or token that is stored following this process to obtain basic profile information say a users email or their profile photo.
From what I have read online this is merely a azureId that stored not the google profile ID which I would use with the google+apis.
Has anyone got a reference that shows a novice programmer how to get the email address or userId required to use the google api.
The only reference I can find is a blog post from 2014. Surely there must be an easier way. And one specifically written to work on Mobile apps as opposed to mobile services. Blog post describing how to expand on authentication with google on mobile services which is no use
Here is my process
// We first try to load a token cache if one exists.
Log.v(TAG, "Click"+USERIDPREF );
if (loadUserTokenCache(mClient))
{
Log.v(TAG, "table" +mClient.getCurrentUser().toString());
createTable();
returnHome();
}
// If we failed to load a token cache, login and create a token cache
else
{
// Login using the Google provider.
final ListenableFuture<MobileServiceUser> mLogin = mClient.login(MobileServiceAuthenticationProvider.Google);
Futures.addCallback(mLogin, new FutureCallback<MobileServiceUser>() {
#Override
public void onFailure(Throwable exc) {
Log.v(TAG, "Login On fail " +exc.getMessage() );
}
#Override
public void onSuccess(MobileServiceUser user) {
Log.v(TAG, "On Success" );
createTable();
cacheUserToken(mClient.getCurrentUser());
Log.v(TAG, "On Success" + mClient.getCurrentUser() );
returnHome();
}
});
}
The first documentation link you posted has the answer. From https://azure.microsoft.com/en-us/documentation/articles/app-service-authentication-overview/#working-with-user-identities-in-your-application:
Code that is written in any language or framework can get the information that it needs from these headers. For ASP.NET 4.6 apps, the ClaimsPrincipal is automatically set with the appropriate values.
Your application can also obtain additional user details through an HTTP GET on the /.auth/me endpoint of your application. A valid token that's included with the request will return a JSON payload with details about the provider that's being used, the underlying provider token, and some other user information. The Mobile Apps server SDKs provide helper methods to work with this data. For more information, see How to use the Azure Mobile Apps Node.js SDK, and Work with the .NET backend server SDK for Azure Mobile Apps.
So to summarize, you have different options depending on which language you use, but the most cross-platform option is to send an authenticated request to your mobile app's /.auth/me endpoint. You'll get back a JSON object which contains a bunch of user claims (name, provider-specific ID, email, etc.).
Related
As the title says, I'm trying to use the Google Sign-In API with a Spring Boot backend server, as described here.
Just to describe the context, the Spring backend is basically a resource+authentication server, that is currently providing Oauth2 authentication to a second spring boot application containing the frontend website, via Google SSO or simple form login (similar to what's described here).
My original idea was to mimic the #EnableOauth2Sso annotation by simply providing an access token to the android app and attach it to every request as "Bearer ".
Using the user credentials for this was pretty straightforward: I simply make a request to the server at "/oauth/token", using those credentials inserted by the user as authentication and I correctly receive the access token.
Now, I have absolutely no idea on how to build a similar procedure with the Google API in Android. The tutorial page I linked before describes how to get a token ID and how the server should validate it, but after that I don't know what to do.
So far I've managed to add a filter to the security chain that simply checks the token like this:
private Authentication attemptOpenIDAuthentication(#NonNull String tokenString){
String clientId = authServices.getClientId();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, factory)
.setAudience(Arrays.asList(clientId, androidClient))
.build();
try {
GoogleIdToken token = verifier.verify(tokenString);
if (token != null) {
return authServices.loadAuthentication(token.getPayload());
} else {
throw new InvalidTokenException("ID token is null");
}
} catch (GeneralSecurityException | IOException e) {
throw new BadCredentialsException("Could not validate ID token");
}
}
This manages indeed to create an Authentication object, but how can I generate an access token after the authentication filtering?
To recap, so far I've got:
The Android app successfully retrieves the Google token ID and sends it to the server
The server sucessfully intercepts the request and validates the token
I'm basically missing the third point where I return a proper access token to the Android client.
Here you are a simple scheme to better understand the situation:
Is there any other way to validate the token and get an access token from the server, or should I completely change the authentication procedure on Android?
As far as I can tell: Yes, you need an access token from the server. If I understand this correctly, a webapp is already authenticated via Oauth on your backend, so the procedure is similar here: Load the user with the google-ID and generate a token. In my application I used a JWT which is valid for 30 days. If the token expires, the Google authentication in the app is usually still valid, so the token can be renewed using the Google ID. With Oauth you can also send a refresh-token directly.
It is important that the app always checks the Google authentication first and only in a second step that of the backend.
For the Authentication process on the backend u may need to manually implement a dedicated securityConfiguration for this. Have a look at the jhipster project, they implemented a custom jwt-authentication which may give you an idea how it works.
Hello all i am making an android app in whiich i have multiple account login at a time now my question is that i for multiple logins i should use sessions to verify every account user that is logged in. Now i am using express on the server side i have read a lot of documentation on storing sessions in node.js
Express-session (Though it is only good for development but not for production but not for my app)
Cookie-session
connect-Redis
connect-mongo
I have also heard about json web tokens where i can generate unique tokens and then i can pass the tokens to the client using res.json({user_id:"user1", token: "generated_token here"})
I have also heard about passport but dont know how it is going to do this also as in passport i use express-session by default will it be good for production or not ??
Now my first question is i have read all of there docs and nowhere it is mentioned where i am creating unique tokens for every user that is signing up.
Second question as i am using my server for android app there will be no use of cookie i will be sending user token as in parameter req.body.token now how to cmpare this with current user_id.
Actually i dont get the flow of control i mean how everything is going on in session in node.js. Also what is this secret is this thing generating unique tokens or what. Also i mean about 100000 of users are registered for my app now please tell me accordingly which way should i use for my app.
I have asked this question previously but there i did not mention that as i am not making a website how to do this(As in my case there will be no use of tokens)
I know this question i am asking is very vague but please bear with me i just want to understand how sessions are used in node.js
Thanks Anways
I'll try to answer this, but it is vague (as you pointed out). I'm going to make an assumption that your Android app is a native Android app and is going to be connecting to some sort of NodeJS backend in the cloud that is based on ExpressJS. If that's not the case, please clarify your thoughts in an update to your question.
The best idea for this specific scenario is to look to the cloud provide. Azure App Service Mobile Apps, for example, allows you to implement authentication - it eventually returns a JSON Web Token (http://jwt.io) to authenticate each request.
If you don't want to be beholden to a cloud provider, but want to run it yourself, you are going to have to implement the token generation and checking yourself. This generally follows the form:
Set up a WebAPI endpoint (maybe /signin) which takes whatever token the identity provider gives you, verifies the information and returns a JWT - there is an NPM module (jsonwebtoken) for producing the JWT. Ensure the JWT includes the identity of your user. I tend to use email address for the identity.
Your Android application will do a WebAPI request to your backend with an Authorization header, the value of which is "Bearer "
Your NodeJS API will use JWT authorization to validate the JWT and extract the user identity so you can use it in your API logic.
The important thing to note in this specific scenario is that your backend code is implementing a WebAPI - there are no cookies nor sessions in the API. The only thing that is linking the user from the client code to the backend code is the JWT.
As a short piece of code, here is how you verify a JWT:
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var jwtCheck = jwt({
secret: new Buffer('your-jwt-secret', 'base64'),
audience: 'your-jwt-audience'
});
app.get('/api/protected', jwtCheck, (req, res) => {
// Your code here
});
app.listen(process.env.PORT || 3000);
I want to receive the public posts of a defined facebook page in my app. I already integrated the FacebookSDK and created a new app in the Facebook developer console. My Request looks like this:
new Request(
null,
"/176063032413299/feed",
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
tv.setText(response.getRawResponse());
}
}
).executeAsync();
The server answers, that I need an acceess token. But I don't want my users to be logged in, when they use my app. So is there an option to get an access token without being logged in? I only want to read public data. I am not interested in publishing or reading private posts.
If I use the app access token like this, it still does not work:
new Request(
null,
"/176063032413299/feed?access_token=xxx",
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
tv.setText(response.getRawResponse());
}
}
).executeAsync();
I get the response:
"Invalid OAuth access token signature"
Even for public posts, you have to authorize the user in order to get access. Either with read_stream to get ALL posts or with user_status to get the posts of the user only.
read_stream will most likely not get approved by Facebook though, see this document: https://developers.facebook.com/docs/facebook-login/permissions/v2.2
Keep in mind that "public" does not mean you can grab it without user authorization. Apps can´t just scrape what they want - scraping is not allowed anyway: https://www.facebook.com/apps/site_scraping_tos_terms.php
Also, of course you can´t create a User Token (which is what you need) without user interaction (login and authorization). Detailed information about Access Tokens can be found in the following links:
https://developers.facebook.com/docs/facebook-login/access-tokens/
http://www.devils-heaven.com/facebook-access-tokens/
Btw, the docs mention that "Any valid access token is required to view public links." - So you may be able to get links only.
Source: https://developers.facebook.com/docs/graph-api/reference/v2.2/user/feed
For debugging Access Tokens, use the Facebook Debugger: https://developers.facebook.com/tools/debug/
Edit: I just realized that you just want to grab the public feed of a Facebook Page, not a User Profile. For that, you can just use an App Access Token. It´s never expiring and easy to create: App-ID|App-Secret. Check out the docs for more information. Keep in mind that you would need to use a User Token or Page Token if the Page is restricted by age or country.
Have a look at https://developers.facebook.com/docs/graph-api/reference/v2.2/page/feed/
The permissions needed to be able to request /{page_id}/feed:
An access token is required to view publicly shared posts.
A user access token is required to retrieve posts visible to that person.
A page access token is required to retrieve any other posts.
Meaning you could generate a long-living Page Access Token to be able to retrieve the public Page Posts. As you won't want to store an expiring Access Token in your App, you'll have to create a backend web service to proxy the requests between the Graph API and your app.
See
https://developers.facebook.com/docs/facebook-login/access-tokens/#pagetokens
https://developers.facebook.com/docs/facebook-login/access-tokens/#extendingpagetokens
https://developers.facebook.com/docs/facebook-login/access-tokens/#refreshtokens
You should also be able to use an App Access Token, which is valid indefinitely.
Use client token.
You could also generate and sign your own personal token but you don't want to distribute that.
I'm thinking about how to solve the next problem:
An Android App which I want to connect to facebook, and to a Server backend(Srv).
Server backend(Srv) which I want to connect to facebook.
The server will run a task that will Get all the Friends of the user(on fb), and the user Statuses(on Fb), and store them on it.
Base assumptions:
I use android as a Mobile device
Server is GAE
Entity key in GAE is the user’s FB-id
User Entity contains:
User fb_id
User verified list(FB_ID String)=> friends of the user that have the app) // maybe use HT?
User statuses list(Status text, date, url)=> whatever I can get from a Status of a user in facebook..
Main questions:
Is the Data representation thought out? can it be better?
How do I handle a situation where two users which are connected to one another add the app at the same time- how can I avoid overlapping?
Should the device Authenticate itself, also with the GAE server?
How to Authenticate GAE with FB
Algorithm:
Android side:
User login and get access token from FB
Posting to my server(Srv) FB Token & myUserFBId // Should I use REST protocol or HTTP
POST?
Server side:
A Servlet handles the POST
{
Query FB ->for the user's friends ids(into friendList = arrayList<FBItem))
foreach FBItem item in friendList
{
//check which FB-ids are in my DB
friendEntity = getKey(item.fb_id)
if(friendEntity != null)
{
// friend exists
verifiedFriendsList.add(item.fb_id) //verifiedFriendsList is ArrayList<String>
friendEntity.getVerifiedFriendList().add(myUserFBId)
}
}
Query FB ->for the user's statuses(into statuses = arrayList<StatusItem))
add new FBEntity(myUserFBId, verifiedFriendsList, statuses) to DB }
Thanks
I have not done anything like this but I think you will need to
Ask user to authenticate your application to use FB- Read about OAuth Api of Facebook
Once your app is authenticated with sufficient permissions you can get users data as per your requirements .
Once you get the data you can process it.
Oauth on FB is what you are searching for..
I'll give you my 4 cents:
The questions that should lead you in developing the DS are: (A) On the
server side, How does the data persist? to a File? to a Database? (B) How much of that data is required to perform the calculations you want done, and how do plan to access it (for example, for an O(n) run, I wouldn't use a HashTable) (C) How does the persist / de-persist work? with an ORM? custom queries?
About concurrency, you'll have to explain what's bugging you. People sign in to SO simultaneously all the time.
3/4. Not an android developer, can't help.
I want to obtain a Google Authtoken from the AccountManager that I can send to my Webservice (not hosted on App Engine) to authenticate the User (I just need the email address and eventually his name, if no permission is required for this).
What do I have to use for the "authTokenType" Paramter of the "getAuthToken" method?
And which google Api do I have to use to get the Users Email?
This is doable using OpenID Connect, however it's sort of experimental, so details could change in the future. If you get an OAuth token for the 'https://www.googleapis.com/auth/userinfo.email' or 'https://www.googleapis.com/auth/userinfo.profile' scope you can use it to get user info from https://www.googleapis.com/oauth2/v1/userinfo (including email). Of course the user needs to authorize this.
You should theoretically be able to get the token from AcccountManager using the "oauth2:https://www.googleapis.com/auth/userinfo.profile" as the token type, but that doesn't appear to work on my device (Galaxy Nexus with stock 4.0.4). Since getting a token via the AccountManager doesn't work (at least for now), the only reliable way is to use a WebView and get one via the browser as described here: https://developers.google.com/accounts/docs/MobileApps
There is a demo web app here that does this: https://oauthssodemo.appspot.com
(late) Update: Google Play Services has been released and it is the preferred way to get an OAuth token. It should be available on all devices with Android 2.2 and later. Getting a profile token does work with it, in fact they use it in the demo app
I have had problems with this as well, since I was not able to find anything like a reference. Perhaps this can help you (code copied from an Android example on using the account manager):
Somewhere in an event handler of your Android app, issue a request for an auth token to get the user's email address in Android:
_accountMgr = AccountManager.get(this);
Account [] accounts = _accountMgr.getAccounts();
Account account = accounts[0]; // For me this is Google, still need to figure out how to get it by name.
_accountMgr.getAuthToken(account, AUTH_TOKEN_TYPE, false, new GetAuthTokenCallback(), null);
In the callback, extract the access token:
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
public void run(AccountManagerFuture<Bundle> result) {
Bundle bundle;
try {
bundle = result.getResult();
final String access_token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
// store token somewhere you can supply it to your web server.
} catch (Exception e) {
// do something here.
}
}
}
Make some request to your web server, supplying the access token.
On the web server, validate the access token and obtain the email address:
curl -d 'access_token=<this is the token the app sent you>' https://www.googleapis.com/oauth2/v1/tokeninfo
You should get something like this:
{
"issued_to": "<something>.apps.googleusercontent.com",
"audience": "<something>.apps.googleusercontent.com",
"scope": "https://www.googleapis.com/auth/userinfo.email",
"expires_in": 3562,
"email": "<users email address>",
"verified_email": true,
"access_type": "online"
}
or if something went wrong:
{
"error": "invalid_token",
"error_description": "Bad Request"
}
You can get the User's name with the Google+ People API. (It will not provide the user's email address).
If this is OK, you can use "Know who you are on Google" as the authTokenType.
There is a sample application provided by Google that demonstrates how to use the AndroidAccountManager in conjunction with the Google+ APIs.
Link: http://code.google.com/p/google-plus-java-starter/source/browse/#hg%2Fandroid