如何从 Azure Mobile/App 服务中检索用户的附加信息?
How to retrieve user's additional information from Azure Mobile/App Services?
我需要从 Facebook 和 Google+ 等社交帐户获取用户的额外信息。当我第一次阅读 Azure 移动服务时,我认为它是社交身份验证的圣杯。好吧,经过整整一周的拔毛,我开始重新考虑我的第一印象。它确实尽可能容易地进行身份验证。我将 Google+ 和 FB 配置为与 Azure 一起使用,将 Azure 配置为使用来自每个提供商的 key/secret 并且一切正常。我能够完美登录。当我试图从登录用户那里获取信息时,问题就开始了,老实说,我认为这是 basic!
Azure 移动服务 returns UserId 和令牌,您不能使用它来请求有关所选提供商的额外信息。因此,即使我使用 FB 的图表 API 创建第二个请求,那也行不通(我试过了!)。该令牌是 Azure 自己的令牌。所以我从 Carlos Figueira(Azure 的 SE)的几篇文章中发现我应该自定义我的 Azure 脚本,向 Azure 发出请求然后我就能让它工作。
我还阅读了 Carlos Figueira 的几篇关于如何实现该额外功能的文章,尽管这不是我想要的(自定义服务器),但我还是决定使用它。但是我的 return 类型是 MobileServiceUser
并且该类型只有 2 个属性:UserId 和 MobileServiceAuthenticationToken。因此,即使在从 Carlos 添加服务器脚本后,我也无法从我的 Xamarin 应用程序中检索额外信息。
我读了很多东西,研究了很多但找不到答案 =/ 顺便说一下,这不是答案:
有没有人设法让它发挥作用?
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();
}
}
});
}
你说的是客户端的令牌,对吗?该令牌仅特定于客户端。如果您使用的是服务器端流程,则服务器是唯一具有该令牌的服务器。如果您想将其发送给客户端,则需要通过您创建的自定义 API 来实现。
您所说的 class 只包含这两个属性。但是在您的服务器端,您的 ServiceUser 可以访问不同的身份提供者令牌,以便与这些服务器 APIs 交谈。您链接的 post 访问令牌的方式是正确的,您弄错了可以访问该令牌的位置,它仅在服务器端(如果您使用服务器定向登录流程)。
这是我在移动服务中用于 return 登录用户配置文件的自定义 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 });
}
}
});
};
我需要从 Facebook 和 Google+ 等社交帐户获取用户的额外信息。当我第一次阅读 Azure 移动服务时,我认为它是社交身份验证的圣杯。好吧,经过整整一周的拔毛,我开始重新考虑我的第一印象。它确实尽可能容易地进行身份验证。我将 Google+ 和 FB 配置为与 Azure 一起使用,将 Azure 配置为使用来自每个提供商的 key/secret 并且一切正常。我能够完美登录。当我试图从登录用户那里获取信息时,问题就开始了,老实说,我认为这是 basic!
Azure 移动服务 returns UserId 和令牌,您不能使用它来请求有关所选提供商的额外信息。因此,即使我使用 FB 的图表 API 创建第二个请求,那也行不通(我试过了!)。该令牌是 Azure 自己的令牌。所以我从 Carlos Figueira(Azure 的 SE)的几篇文章中发现我应该自定义我的 Azure 脚本,向 Azure 发出请求然后我就能让它工作。
我还阅读了 Carlos Figueira 的几篇关于如何实现该额外功能的文章,尽管这不是我想要的(自定义服务器),但我还是决定使用它。但是我的 return 类型是 MobileServiceUser
并且该类型只有 2 个属性:UserId 和 MobileServiceAuthenticationToken。因此,即使在从 Carlos 添加服务器脚本后,我也无法从我的 Xamarin 应用程序中检索额外信息。
我读了很多东西,研究了很多但找不到答案 =/ 顺便说一下,这不是答案:
有没有人设法让它发挥作用?
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();
}
}
});
}
你说的是客户端的令牌,对吗?该令牌仅特定于客户端。如果您使用的是服务器端流程,则服务器是唯一具有该令牌的服务器。如果您想将其发送给客户端,则需要通过您创建的自定义 API 来实现。
您所说的 class 只包含这两个属性。但是在您的服务器端,您的 ServiceUser 可以访问不同的身份提供者令牌,以便与这些服务器 APIs 交谈。您链接的 post 访问令牌的方式是正确的,您弄错了可以访问该令牌的位置,它仅在服务器端(如果您使用服务器定向登录流程)。
这是我在移动服务中用于 return 登录用户配置文件的自定义 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 });
}
}
});
};