[英]Meteor.js facebook login with 'apple-mobile-web-app-capable'
我正在開發一個小型個人項目,用戶可以通過內置{{loginButtons}}
內置的Meteor.js登錄Facebook。但問題是,當通過apple-mobile-web-app-capable
全屏運行應用程序時apple-mobile-web-app-capable
沒有彈出對話框要求許可。 屏幕空白。
我根本不使用facebook的sdk。
它在移動野生動物園中運行良好。 我已將它部署到meteor進行最后的測試,所以它不是localhost問題。
這是否可能無需創建我自己的用戶創建和/或服務器端實現,和/或Facebook的sdk? 最終我計划增加更多,比如twitter和google。
另外,我還在使用iOS 6.1
更新,請參閱我的其他答案,以獲得更好的改進示例
所以我花了大約一個小時搞清楚一些東西。 我認為最好的辦法是放棄Meteor的內置帳戶系統而不是我使用'oauth.io'(沒有隸屬關系)和'流星路由器'而我將使用Meteor的Accounts.createUser()創建用戶; 最好的部分是,它適用於localhost和我的iPhone,所以我不必繼續部署它進行測試。
Meteor.startup(function () {
OAuth.initialize('my key');
});
我的路線:
Meteor.Router.add({
'/oauth': function() {
console.log('oauthed');
OAuth.callback('facebook', function(err, result) {
var token = result.access_token;
var url = 'https://graph.facebook.com/me?access_token='+token;
$.get( url, function( data ) {
alert(data.email)
console.log(data);
});
});
}
});
然后一個簡單的錨
$('#loginfb').live('click', function() {
OAuth.redirect('facebook', "/oauth");
});
就我而言,但它適用於apple-mobile-web-app-capable
我可以驗證並獲取我的Facebook信息。 它比我想做的工作更多,但並不太難。
所以我在考慮用這種方法來獲取用戶的電子郵件,然后使用:
Accounts.createUser({
email: data.email,
password: data.id //since your Facebook id can't change
});
這樣用戶可以更改它或稍后重置它,或者我可以提示他們更改它。
然后我要檢查該用戶是否存在,(不知道該怎么做)以及它們是否存在然后執行:
Meteor.loginWithPassword(data.email, data.id);
好。 所以我稍微調整了我的設置。
我不得不切換到Backbone路由器,由於某種原因,Meteor Router每次加載/ oauth時都會刷新頁面兩次。 Backbone沒有。
我添加了一個用於生成密碼的服務器端功能。
Meteor.startup(function () {
Backbone.history.start({
pushState: true,
root: "/"
});
OAuth.initialize('key goes here');
});
var $Router = Backbone.Router.extend({
routes: {
"/": "home",
"oauth": "oauth",
"": "home"
},
home: function () {
console.log('home')
},
oauth: function () {
OAuth.callback('facebook', function (err, result) {
console.log(result);
var token = result.access_token;
var url = 'https://graph.facebook.com/me?access_token=' + token;
$.get(url, function (data) {
var email = data.email;
var pass = Meteor.call('generatePass', data, function (error, result) {
Meteor.loginWithPassword(email, result, function (error) {
if (error) {
var options = {};
options.email = email;
options.password = pass;
Accounts.createUser(options, function (error) {
if (error) {
console.log(error);
$router.navigate('/');
} else {
//Account creation successful return to index
$router.navigate('/');
}
})
} else {
//Login successful return to index
$router.navigate('/');
}
});
});
});
return false;
});
}
});
var $router = new $Router();
// I use jquery for events, I don't like to use meteor's template event handlers.
$('#loginfb').click(function (event) {
event.preventDefault();
//have to use redirect, otherwise popup won't work correctly since we're using mobile-webapp-capable
OAuth.redirect('facebook', "/oauth");
});
//server.js
Meteor.methods({
generatePass: function (data) {
// .. do stuff ..
var pass = fancy function that creates a password based on the supplied data;
return pass;
}
});
到目前為止,它只適用於Facebook,並沒有很好的測試。 我喜歡一些指導和/或建設性的批評。
問題似乎是oauth包使用window.open打開一個彈出窗口。 我之前沒有使用過apple-mobile-web-app的經驗,但有些研究似乎暗示window.open無法使用它。 如果客戶端使用可能使用的全屏應用程序,該解決方案似乎正在測試
window.navigator.standalone
不幸的是,oauth登錄工作流程在假設打開彈出窗口時有點尷尬。 我不確定進行此測試的最佳位置是在用戶在新窗口中輸入用戶名/密碼后是否嘗試登錄或用戶創建。
我嘗試將window.open方法更改為accounts-oauth-helper / oauth_client.js中的window.location,然后打開窗口,但我的redirect_uri問題可能是因為我在手機上的localhost項目中這樣做了所以我不確定一旦登錄發生,登錄過程是否會繼續。
在使用apple-mobile-web-app-capable時,這似乎會影響所有登錄提供商,因此這可能是一個需要修復的錯誤。 我稍后會嘗試設置一個項目,以便更好地了解這個項目並告訴您它是如何進行的。
我想出了一個更好的方法來做這個沒有使用帳戶Facebook和沒有使用Facebook的自己的SD但我使用流星的帳戶和帳戶-ui(不是我真的需要它,它只是方便)
客戶端上的事件處理程序
Template.header.events({
'click #loginFB': function(e) {
e.preventDefault();
OAuth.redirect('facebook', "/oauthlink");
//or
var url = 'https://www.facebook.com/dialog/oauth?client_id=' +client_id+'&response_type=token&redirect_uri='+redirect;
window.location = url;
}
});
Iron Router的路由從OAuth獲取結果
this.route('oauthLink', {
path: '/oauthlink',
action: function() {
OAuth.callback('facebook', function(err, result) {
Meteor.call('fblogin', result, function(error, result) {
Meteor.loginWithToken(result.token, function(err) {
if(err) {
Meteor._debug("Error logging in with token: " + err);
}
})
});
});
}
});
或沒有oauth.io
this.route('oauthLink', {
path: '/oauthlink',
action: function() {
var str = window.location.hash;
str = str.split('&');
var accessToken = str[0];
var expiresIn = str[1];
accessToken = accessToken.split('=');
expiresIn = expiresIn.split('=');
var result = {
access_token : accessToken[1],
expires_in : expiresIn[1]
};
Meteor.call('fblogin', result, function(error, result) {
console.log(result)
Meteor.loginWithToken(result.token, function(err) {
if(err) {
Meteor._debug("Error logging in with token: " + err);
}
})
});
}
});
不確定'Action'是否是正確的功能(我是鐵路由器的新手),但它確實有效。
然后在服務器上
Meteor.methods({
fblogin: function(response) {
var identity = Meteor.call('$getIdentity', response.access_token);
// synchronous call to get the user info from Facebook
var serviceData = {
accessToken: response.access_token,
expiresAt: (+new Date) + (1000 * response.expires_in)
};
// include all fields from facebook
// http://developers.facebook.com/docs/reference/login/public-profile-and-friend-list/
var whitelisted = ['id', 'email', 'name', 'first_name',
'last_name', 'link', 'username', 'gender', 'locale', 'age_range'];
var fields = _.pick(identity, whitelisted);
_.extend(serviceData, fields);
var stuff = {
serviceName : 'facebook',
serviceData: serviceData,
options: {profile: {name: identity.name}}
};
var userData = Accounts.updateOrCreateUserFromExternalService(stuff.serviceName, stuff.serviceData, stuff.options);
var x = DDP._CurrentInvocation.get();
var token = Accounts._generateStampedLoginToken();
Accounts._insertLoginToken(userData.userId, token);
Accounts._setLoginToken(userData.userId, x.connection, Accounts._hashLoginToken(token.token))
x.setUserId(userData.userId)
return {
id: userData.userId,
token: token.token,
tokenExpires: Accounts._tokenExpiration(token.when)
};
},
$getIdentity: function(accessToken) {
try {
return HTTP.get("https://graph.facebook.com/me", {
params: {access_token: accessToken}}).data;
} catch (err) {
throw _.extend(new Error("Failed to fetch identity from Facebook. " + err.message),
{response: err.response});
}
}
});
幾乎所有fblogin()實際上都來自Meteor自己的賬戶-facebook包。 我只是修改它以滿足我的需要。 $ getIdentity是從那里的逐字副本。
var stuff包含Facebook數據(名稱,訪問令牌等)和流星帳戶數據,並將其放入Accounts.updateorcreateuserfromexternalservice,它構建您的meteor帳戶fblogin()返回userData,它從Accounts.updateorcreate獲取。 ..並從中獲取您的令牌,您可以通過Metoer.loginWithToken登錄。
所有這些都發生在不打開新窗口或標簽的情況下,就像我使用accounts-facebook一樣。 因此,修復我的主要問題,並作為額外的獎勵,它似乎在功能上等同於使用accounts-facebook。 不再檢查用戶是否存在,如果是,登錄,使用“生成的密碼”,或者如果它們不存在,則創建它們,然后使用“生成的密碼”登錄
當然,這可以擴展到其他oauth apis,你顯然不需要oauth.io。 我只是懶惰。 希望其他人覺得這很有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.