如何在 OAuth 之后使用 built-in accounts-ui 包在 Meteor v1.4+ 中填充客户端 Meteor.user.services?

How to populate client-side Meteor.user.services after OAuth with built-in accounts-ui package in Meteor v1.4+?

我在 Meteor v1.4.1 中使用 accounts-uiaccounts-google。我无法让 user.services 对象出现在客户端代码中。特别是,我需要 google 的头像。

我已将服务器端代码配置为使用 Google 进行身份验证,如下所示:

import { Meteor } from 'meteor/meteor';
import { ServiceConfiguration } from 'meteor/service-configuration';

const services = Meteor.settings.private.oauth;
for (let service of Object.keys(services)) {
  ServiceConfiguration.configurations.upsert({
    service
  }, {
    $set: {
      clientId: services[service].app_id,
      secret: services[service].secret,
      loginStyle: "popup"
    }
  });
}

...以及用于配置权限的客户端代码,如下所示:

Accounts.ui.config({
  requestPermissions: {
    google: ['email', 'profile']
  },
  forceApprovalPrompt: {
    google: true
  },
  passwordSignupFields: 'EMAIL_ONLY'
});

当用户单击 'Sign-In with Google' 按钮时,会出现一个弹出窗口,他们可以进行身份​​验证。然而,尽管 forceApprovalPrompt 对于 google.

设置为真,但没有出现提示

最大的问题是当我执行这个时,

const user = Meteor.user();
console.log(user.services);

在客户端代码的任何地方,我都没有看到预期的用户服务信息。我检查了我的数据库,它肯定在那里:

$ mongo localhost:27017
> db.users.find({})
> ... "services" : { "google" : { "accessToken" : ... } } ...

我很好奇我错过了什么?我是否应该显式定义 publish 函数以使用户服务数据存在于客户端中?

出于安全原因,服务 属性 有意隐藏在客户端。这里有几种方法:

建议

  1. 我更喜欢的是公开一个流星方法给你带来 public 在您需要的几个地方可能需要的钥匙和头像 他们。
  2. 登录成功后,您可以在用户对象的某处记录您需要的数据,但在服务之外 属性。
  3. 如您所说,您可以创建一个新的 publication,明确指定要检索的字段和要隐藏的字段。不过,您必须小心发布内容。

代码示例

  1. 流星方法:
// server
Meteor.methods({
    getProfilePicture() {
        const services = Meteor.user().services;
        // replace with actual profile picture property
        return services.google && services.google.profilePicture;
    }
});

// client
Meteor.call('getProfilePicture', (err, profilePicture) => {
    console.log('profile picture url', profilePicture);
});
  1. 关于成功创建用户的更新(您可能还希望有一个登录挂钩以反映 google 中的任何 avatar/picture 更改):
// Configure what happens with profile data on user creation
Accounts.onCreateUser((options, user) => {
  if (!('profile' in options)) { options.profile = {}; }
  if (!('providers' in options.profile)) { options.profile.providers = {}; }
  // Define additional specific profile options here
  if (user.services.google) {
    options.profile.providers.google = {
      picture: user.services.google.picture
    }
  }
  user.profile = options.profile;
  return user;
});
  1. 仅发布 select 数据...
// Server
Meteor.publish('userData', function () {
  if (this.userId) {
    return Meteor.users.find({ _id: this.userId }, {
      fields: { other: 1, things: 1 }
    });
  } else {
    this.ready();
  }
});
// Client
Meteor.subscribe('userData');