How to retrieve user's additional information from Azure Mobile/App Services?

孤街醉人 提交于 2019-12-22 01:17:32

问题


I need to get the user's extra information from social accounts like Facebook and Google+. When I first read about Azure Mobile Services I thought it to be the holy grail of social authentication. Well, after a full week of hair pulling I'm starting to reconsider my first impression. It does authenticate as easily as it could possibly do. I configured Google+ and FB to work with Azure, configured Azure to use the key/secret from each provider and it all just worked. I was able to login perfectly. The problem started when I tried to get information from the logged user, which I honestly think is basic!

Azure Mobile Services returns the UserId and a Token that you can not use to request the extra info on the selected provider. So even if I were to create a second request using FB's graph API for instance, that wouldn't work (I've tried!). That token is Azure's own token. So I found out from several Carlos Figueira (SE at Azure) posts that I should customize my Azure script, make a request to Azure and then I'd be able to get it working.

I've also read several posts from Carlos Figueira on how to implement that extra functionality and even though that was not what I was looking for (customizing the server) I decided to work with that. But my return type is a MobileServiceUser and that type only has 2 properties: UserId and MobileServiceAuthenticationToken. So even after adding the server script from Carlos I couldn't retrieve the extra information from my Xamarin App.

I've read a lot of things, researched a lot and couldn't find an answer =/ By the way this is not the answer: How to get user name, email, etc. from MobileServiceUser?

Did anyone manage to make it work?

PS: I'm not posting any code here because it's working. If you think checking some part of my code would help decipher the problem just let me know.

Thanks in advance!

EDIT:

Script

function insert(item, user, request) {
    item.UserName = "<unknown>"; // default
    user.getIdentities({
        success: function (identities) {
            var url = null;
            var oauth = null;
            if (identities.google) {
                var googleAccessToken = identities.google.accessToken;
                url = 'https://www.googleapis.com/oauth2/v3/userinfo?access_token=' + googleAccessToken;
            } else if (identities.facebook) {
                var fbAccessToken = identities.facebook.accessToken;
                url = 'https://graph.facebook.com/me?access_token=' + fbAccessToken;
            } else if (identities.microsoft) {
                var liveAccessToken = identities.microsoft.accessToken;
                url = 'https://apis.live.net/v5.0/me/?method=GET&access_token=' + liveAccessToken;
            } else if (identities.twitter) {
                var userId = user.userId;
                var twitterId = userId.substring(userId.indexOf(':') + 1);
                url = 'https://api.twitter.com/1.1/users/show.json?user_id=' + twitterId;
                var consumerKey = process.env.MS_TwitterConsumerKey;
                var consumerSecret = process.env.MS_TwitterConsumerSecret;
                oauth = {
                    consumer_key: consumerKey,
                    consumer_secret: consumerSecret,
                    token: identities.twitter.accessToken,
                    token_secret: identities.twitter.accessTokenSecret
                };
            }

            if (url) {
                var requestCallback = function (err, resp, body) {
                    if (err || resp.statusCode !== 200) {
                        console.error('Error sending data to the provider: ', err);
                        request.respond(statusCodes.INTERNAL_SERVER_ERROR, body);
                    } else {
                        try {
                            var userData = JSON.parse(body);
                            item.UserName = userData.name;
                            request.execute();
                        } catch (ex) {
                            console.error('Error parsing response from the provider API: ', ex);
                            request.respond(statusCodes.INTERNAL_SERVER_ERROR, ex);
                        }
                    }
                }
                var req = require('request');
                var reqOptions = {
                    uri: url,
                    headers: { Accept: "application/json" }
                };
                if (oauth) {
                    reqOptions.oauth = oauth;
                }
                req(reqOptions, requestCallback);
            } else {
                // Insert with default user name
                request.execute();
            }
        }
    });
}

回答1:


You're talking about the token on the client side correct? That token is specific only to the client. If you're using Server Side flow, the server is the only one with that token. If you want to send that to the client, you need to do that via a custom API you create.

This class you're talking about does only contain those two properties. But on your server side, your ServiceUser can access the different identity provider tokens in order to speak to those servers APIs. Your linked post is correct in how you access the token, you're mistaken on where you can access that token, it's only on the server side (if you use the server directed login flow).




回答2:


Here is the custom API Script I had working in Mobile Services to return the profile of the logged in user. I am working on updating to Mobile Apps as some environment variables appear to have changed. Would love to know if anyone has gotten it to work with Mobile Apps.

exports.get = function (request, response) {
var user = request.user;
user.getIdentities({
    success: function (identities) {
        var req = require('request');
        var url = null;
        var oauth = null;
        var userId = user.userId.split(':')[1];
        console.log('Identities: ', identities);
        if (identities.facebook) {
            url = 'https://graph.facebook.com/me?access_token=' +
                identities.facebook.accessToken;
        } else if (identities.google) {
            url = 'https://www.googleapis.com/oauth2/v3/userinfo' +
                '?access_token=' + identities.google.accessToken;
        } else if (identities.microsoft) {
            url = 'https://apis.live.net/v5.0/me?access_token=' +
                identities.microsoft.accessToken;
        } else if (identities.twitter) {
            var consumerKey = process.env.MS_TwitterConsumerKey;
            var consumerSecret = process.env.MS_TwitterConsumerSecret;
            oauth = {
                consumer_key: consumerKey,
                consumer_secret: consumerSecret,
                token: identities.twitter.accessToken,
                token_secret: identities.twitter.accessTokenSecret
            };
            url = 'https://api.twitter.com/1.1/users/show.json?' +
                'user_id=' + userId + '&include_entities=false';
        } else {
            response.send(500, { error: 'No known identities' });
            return;
        }

        if (url) {
            var reqParams = { uri: url, headers: { Accept: 'application/json' } };
            if (oauth) {
                reqParams.oauth = oauth;
            }
            req.get(reqParams, function (err, resp, body) {
                if (err) {
                    console.error('Error calling provider: ', err);
                    response.send(500, { error: 'Error calling provider' });
                    return;
                }

                if (resp.statusCode !== 200) {
                    console.error('Provider call did not return success: ', resp.statusCode);
                    response.send(500, { error: 'Provider call did not return success: ' + resp.statusCode });
                    return;
                }

                try {
                    var userData = JSON.parse(body);
                    response.send(200, userData);
                } catch (ex) {
                    console.error('Error parsing response: ', ex);
                    response.send(500, { error: ex });
                }
            });
        } else {
            response.send(500, { error: 'Not implemented yet', env: process.env });
        }
    }
});

};



来源:https://stackoverflow.com/questions/31213502/how-to-retrieve-users-additional-information-from-azure-mobile-app-services

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!