Android 使用 Loopback.io 和 Passport.js 登录本机 FB?

Android Native FB Login with Loopback.io and Passport.js?

我正在为我的应用程序构建一个 android 客户端,它已经有一个网络客户端并使用 loopback-component-passport 进行 FB 身份验证。

我能够通过我的 Android 应用程序从 FB 成功获取 access_token。

我发现带环回的默认护照组件通过使用授权码对回调 url 执行 GET 来工作,然后从 FB 获取 access_token。由于我已经有了 access_token,我该如何绕过这个授权代码步骤,以便我可以仅使用护照处理用户创建的剩余逻辑,否则我将有两个不同的代码来处理 FB 登录。

passport.js 的当前版本没有任何可以简单地将 Android 本机 FB 登录与环回+密码集成的功能。

难以集成的原因是,当使用 Web 进行身份验证时,FB 回调的环回端点会收到一个身份验证令牌,然后使用该令牌创建一个 access_token,而在本机 FB 登录的情况下,通过FB app,一个直接获取access_token。

整合步骤如下:

  1. 设置您的用户模型。假设您从环回模型扩展标准用户模型。

  2. 设置一个单独的模型来存储我们将获得的凭据 来自 FB,即 access_token、ttl 等。我们称它为 FacebookAccessToken。还设置与用户模型的关系。 user.hasOne(FacebookAccessToken)FacebookAccessToken.belongTo(user)

{ "name": "FacebookAccessToken", "base": "PersistedModel", "idInjection":错误, "options":{ "validateUpsert":真 }, "properties":{ "FbUserId":{ "type": "string", "id": 是的, "required":真 }, "token":{ "type": "string", "required":真 }, "expires":{ "type": "date", "required":真 }, "userId":{ "type": "string", "required":真 } }, "validations": [], "relations":{ "user":{ "type": "belongsTo", "model": "user", "foreignKey": "userId" } }, "acls": [], "methods": [] }</p> <p>

  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 并将其作为条目添加到您的 providers.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 它将 return json 与来自回送的用户访问令牌和用户的 userId

这仍将创建 UserIdentities 等,无需任何额外配置

注意 "strategy" 实际上可以是任何随机字符串,因为 passport-facebook-token 现在不需要 .Strategy 但有必要在选项中输入一些内容,以便 loopback-component-passport默认要求模块没有附加 .Strategy