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.

Шаги для интеграции следующие:

  1. Настройте свою модель пользователя. Предположим, что вы расширяете стандартную модель User из моделей Loopback.

  2. Настройте отдельную модель, в которой будут храниться учетные данные, которые мы получим от 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": [] }

  1. Создайте пользовательский удаленный метод в вашей пользовательской модели (скажем, 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 требовался модуль без.Стратегия добавлена

Другие вопросы по тегам