Android Native FB Войти через Loopback.io и Passport.js?
Я создаю Android-клиент для моего приложения, которое уже имеет веб-клиент и использует loopback-component-passport для аутентификации FB.
Я могу успешно получить access_token от FB через мое приложение для Android.
Я выяснил, что компонент паспорта по умолчанию с обратной связью работает, выполняя GET для URL обратного вызова с кодом авторизации, который затем получает access_token от FB. Поскольку у меня уже есть access_token, как я могу обойти этот шаг кода авторизации, чтобы я мог обрабатывать оставшуюся логику создания пользователя, используя только паспорт, иначе у меня будет два разных кода, обрабатывающих логин FB.
2 ответа
В текущей версии passport.js нет ничего, что позволяло бы просто интегрировать логин Android Native FB с loopback+passport.
Причина, по которой его трудно интегрировать, состоит в том, что когда кто-то аутентифицируется с помощью веб-интерфейса, конечная точка обратной связи FB-обратного вызова получает токен аутентификации, который он затем использует для создания access_token, в то время как в случае встроенного входа в FB через приложение FB один получает непосредственно access_token.
Шаги для интеграции следующие:
Настройте свою модель пользователя. Предположим, что вы расширяете стандартную модель User из моделей Loopback.
Настройте отдельную модель, в которой будут храниться учетные данные, которые мы получим от FB, т.е. access_token, ttl и т. Д. Давайте назовем это FacebookAccessToken. Также настройте отношения с моделью пользователя.
user.hasOne(FacebookAccessToken)
а такжеFacebookAccessToken.belongTo(user)
{
"name": "FacebookAccessToken",
"base": "PersistedModel",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"FbUserId": {
"type": "string",
"id": true,
"required": true
},
"token": {
"type": "string",
"required": true
},
"expires": {
"type": "date",
"required": true
},
"userId": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"user": {
"type": "belongsTo",
"model": "user",
"foreignKey": "userId"
}
},
"acls": [],
"methods": []
}
- Создайте пользовательский удаленный метод в вашей пользовательской модели (скажем, loginWithFB), который будет принимать access_token в качестве параметра. Используйте этот токен доступа, чтобы получить необходимую информацию из Facebook, чтобы создать новый экземпляр пользователя и сохранить кредиты в UserCredential. Следующий код будет в
user.js
,
ПРИМЕЧАНИЕ. - Необходимо установить фиктивный пароль для каждого пользователя. Я бы посоветовал вам установить это на что-то загадочное, чтобы никто не взломал вашу систему (не забудьте добавить немного соли). Также, если вы не разрешаете вход с простым паролем, отключите конечную точку /login
User.loginWithAccessToken = function (accessToken,cb) {
FB.setAccessToken(accessToken);
FB.api('me', function (res) {
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
var err = new Error('Invalid Access Token');
err.statusCode = 401;
cb(err);
return;
}
// accessToken is valid, so
var query = { email : res.email};
User.findOne({where:query}, function (err,user){
var defaultError = new Error('login failed');
defaultError.statusCode = 401;
defaultError.code = 'LOGIN_FAILED';
if(err){
cb(defaultError);
}else if(!user){
// User email not found in the db case, create a new profile and then log him in
User.create({email: query.email, password: DUMMY_PASS}, function(err, user) {
if(err){
cb(defaultError);
}else{
User.login({ email: query.email, password: DUMMY_PASS}, function(err,accessToken){
cb(null,accessToken);
});
}
});
}
else{
// User found in the database, so just log him in
User.login({ email: query.email, password: DUMMY_PASS}, function(err,accessToken){
if(err){
cb(defaultError);
}else{
cb(null,accessToken);
}
});
}
});
});
};
User.remoteMethod(
'loginWithAccessToken',
{
description: 'Logins a user by authenticating it with an external entity',
accepts: [
{ arg: 'external_access_token', type: 'string', required: true, http: { source:'form'} }
],
returns: {
arg: 'accessToken', type: 'object', root: true,
description:
'The response body contains properties of the AccessToken created on login.\n' +
'Depending on the value of `include` parameter, the body may contain ' +
'additional properties:\n\n' +
' - `user` - `{User}` - Data of the currently logged in user. (`include=user`)\n\n'
},
http: {verb: 'post'}
}
);
Вы можете установить passport-facebook-token и добавить его в качестве записи в свой файл provider.json, например:
"facebook-token": {
"provider": "facebook-mobile",
"module": "passport-facebook-token",
"clientID": "CLIENT_ID",
"clientSecret": "CLIENT_SECRET",
"callbackPath": "/auth/facebook/token",
"failureFlash": true,
"strategy": "FBTokenMobileStrategy",
"json": true,
"session": false
}
затем вы можете позвонить в /auth/facebook/token?access_token=PASS_YOUR_ACCESS_TOKEN_HERE и он вернет json с маркером доступа пользователя из loopback и userId пользователя
это все равно создаст UserIdentities и т. д. без дополнительной настройки
обратите внимание, что "стратегия" действительно может быть любой случайной строкой, потому что токен passport-facebook-token теперь не нуждается в.Strategy, но здесь необходимо ввести что-то здесь в опциях, чтобы по умолчанию для loopback-component-passport требовался модуль без.Стратегия добавлена