1

I inherited a Windows 8 application that is written with XAML. So in C# when I make this call

user = await MobileServices.MobileService
                    .LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);

(This is for Azure Mobile Services)

The user object is ONLY giving me the Token and the MicrosoftAccount:..............

In order to get to authenticate people, I need to be able to see WHO is requesting access...

I looking at articles like below, but I seem to be missing something? Is this javascript in the article something I would have to write in Node.js?

Example article: http://blogs.msdn.com/b/carlosfigueira/archive/2013/12/12/expanded-login-scopes-in-azure-mobile-services.aspx

Tom Stickel
  • 19,633
  • 6
  • 111
  • 113

1 Answers1

1

Currently to be able to get more information about the logged in user, you need to make a second call to the service to retrieve the user info. You don't really need to ask for additional login scopes (the topic of the post you mentioned) to retrieve the user name, since that is given by default for all the providers.

This post should have the code you need to write in the server side (node.js) to get more information about the logged in user. The TL;DR version is given below:

On the server side: add this custom API (I'll call it "userInfo"; set the permission of GET to "user", and all others to admin):

exports.get = function(request, response) {
    var user = request.user;
    user.getIdentities({
        success: function(identities) {
            var accessToken = identities.microsoft.accessToken;
            var url = 'https://apis.live.net/v5.0/me/?method=GET&access_token=' + accessToken;
            var requestCallback = function (err, resp, body) {
                if (err || resp.statusCode !== 200) {
                    console.error('Error sending data to the provider: ', err);
                    response.send(statusCodes.INTERNAL_SERVER_ERROR, body);
                } else {
                    try {
                        var userData = JSON.parse(body);
                        response.send(200, userData);
                    } catch (ex) {
                        console.error('Error parsing response from the provider API: ', ex);
                        response.send(statusCodes.INTERNAL_SERVER_ERROR, ex);
                    }
                }
            }
            var req = require('request');
            var reqOptions = {
                uri: url,
                headers: { Accept: "application/json" }
            };
            req(reqOptions, requestCallback);
        }
    });
}

On the client side, after a successful login, call that API:

user = await MobileServices.MobileService
    .LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
var userInfo = await MobileServices.MobileService.InvokeApiAsync(
    "userInfo", HttpMethod.Get, null);

userInfo will contain a JObject with the user information. There is an open feature request to make this better at http://feedback.azure.com/forums/216254-mobile-services/suggestions/5211616-ability-to-intercept-the-login-response.

carlosfigueira
  • 85,035
  • 14
  • 131
  • 171
  • Ok, so it sounds like I NEED to add that server Node.js code, where do I add that? I have several db azure tables , so I have a "user" table of which had to default node.js method for CRUD operations. Would this be added there? Then if the node.js code is added with because called "userInfo" , then the c# userInfo has the user information? I feel like I'm missing a piece. – Tom Stickel Apr 18 '14 at 22:38
  • Also, this code seems to not be current var table = MobileService.GetTable("Identities"); var response = await table.ReadAsync(""); var identities = response.GetArray()[0].GetObject(); the response.GetArray .... – Tom Stickel Apr 18 '14 at 22:41
  • The best place would be to add it in a custom API as I mentioned in the answer above (when the blog post was written custom APIs weren't supported yet, which is why the logic was implemented in a table). The call to `InvokeApiAsync` in the client will invoke that API, and since the client is logged in it will send the auth info to the API. The API will take that info (via the call to `user.getIdentities`) and contact the auth provider to get more details about the user. – carlosfigueira Apr 18 '14 at 22:42
  • Just reading your article on creating custom API , right before seeing your comment! thanks , working on it !!! – Tom Stickel Apr 18 '14 at 22:45
  • What is liveAccessToken , that variable gets passed in? Is that going to be a static token that is linked to the live account that is associated with the azure account? – Tom Stickel Apr 18 '14 at 23:16
  • It was a copy/paste error. It should be `accessToken` (the variable created on the previous line). I edited the question to fix it. – carlosfigueira Apr 18 '14 at 23:47
  • You can get e-mail, you'll need to request additional scopes for the login. Take a look at http://blogs.msdn.com/b/carlosfigueira/archive/2013/12/12/expanded-login-scopes-in-azure-mobile-services.aspx for more details. – carlosfigueira Apr 21 '14 at 22:34
  • Ok, so I'm looking at the GettingUserInfoAuthProviders solution, along with that link you sent. So after I do this invoke call i.e. var result = await MobileService.InvokeApiAsync("userinfo", HttpMethod.Get, null); Then it seems that you are saying to "login again" right? Wouldn't that prompt the user to login twice? – Tom Stickel Apr 21 '14 at 22:47
  • No, you shouldn't need to log in more than once. Once you're logged in, you're logged in. – carlosfigueira Apr 21 '14 at 22:53
  • Ok, so I'm missing something, do I need to make a new custom api? – Tom Stickel Apr 21 '14 at 22:58
  • So I obviously do not want to do this. user = await MobileServices.MobileService .LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount); var userInfo = await MobileServices.MobileService.InvokeApiAsync("userInfo", HttpMethod.Get, null); var secondLogin = await MobileServices.MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount); – Tom Stickel Apr 21 '14 at 22:59
  • No. With the same custom API as described above, if you have extra scopes required from the provider, the result of the call to the provider should have the additional information. There's only one login required. – carlosfigueira Apr 22 '14 at 03:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51153/discussion-between-tom-stickel-and-carlosfigueira) – Tom Stickel Apr 22 '14 at 06:12
  • Can somebody provide an answer, how shall we retrieve identities in .NET backend (C#) – Citrus Aug 08 '14 at 22:57