如何从Azure Mobile / App Services检索用户的其他信息?

时间:2015-07-03 19:57:47

标签: azure xamarin azure-mobile-services xamarin.forms

我需要从Facebook和Google+等社交帐户中获取用户的额外信息。当我第一次阅读Azure移动服务时,我认为它是社交认证的圣杯。好吧,经过一整周的拔毛,我开始重新考虑我的第一印象。它尽可能容易地进行身份验证。我将Google+和FB配置为与Azure配合使用,将Azure配置为使用来自每个提供商的密钥/密钥,这一切都刚刚起作用。我能够完美登录。当我试图从登录用户那里获取信息时,问题就出现了,老实说我认为这是基本

Azure移动服务返回UserId和您无法用于请求所选提供商的额外信息的令牌。因此,即使我要使用FB的图形API创建第二个请求,这也行不通(我已经尝试了!)。该令牌是Azure自己的令牌。所以我从几个Carlos Figueira(Azure上的SE)帖子中发现我应该自定义我的Azure脚本,向Azure发出请求然后我就能让它工作。

我还阅读了Carlos Figueira关于如何实现额外功能的几篇文章,即使这不是我想要的(自定义服务器),我决定使用它。但我的返回类型是MobileServiceUser,该类型只有2个属性:UserId和MobileServiceAuthenticationToken。因此,即使从Carlos添加服务器脚本后,我也无法从我的Xamarin App中检索额外信息。

我读了很多东西,研究了很多,找不到答案= /顺便说一下,这不是答案: How to get user name, email, etc. from MobileServiceUser?

有没有人设法让它发挥作用?

PS:我没有在这里发布任何代码,因为它正在运行。如果您认为检查我的代码的某些部分有助于破译问题,请告诉我。

提前致谢!

编辑:

脚本

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();
            }
        }
    });
}

2 个答案:

答案 0 :(得分:2)

您在谈论客户端的令牌是否正确?该令牌仅特定于客户端。如果您正在使用服务器端流,则服务器是唯一具有该令牌的服务器。如果要将其发送到客户端,则需要通过您创建的自定义API执行此操作。

您正在谈论的class只包含这两个属性。但是在服务器端,您的ServiceUser可以访问不同的身份提供者令牌,以便与这些服务器API通信。您链接的帖子在您访问令牌的方式上是正确的,您错误地认为您可以访问该令牌的位置,它只在服务器端(如果您使用服务器控制的登录流程)。

答案 1 :(得分:0)

以下是我在移动服务中工作的自定义API脚本,用于返回登录用户的个人资料。我正在努力更新到移动应用程序,因为一些环境变量似乎已更改。很想知道是否有人使用移动应用程序。

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 });
        }
    }
});

};