Meteor accounts-google Token Expires

前端 未结 1 1637
走了就别回头了
走了就别回头了 2021-01-19 17:13

I have the Accounts-UI config setup to store an offline token for google thusly:

if (Meteor.isClient) {
 Accounts.ui.config({
  requestOfflineToken: { google         


        
相关标签:
1条回答
  • 2021-01-19 17:42

    I recommend using Google API Node JS client to refresh your access tokens.

    https://github.com/google/google-api-nodejs-client/

    It's available as a server-side NPM package, so you might want to use this package to be able to npmRequire it in your Meteor app.

    Use this packages.json config to load the latest googleapis package :

    {
      "googleapis": "2.1.5"
    }
    

    Then in your Meteor server code you'll be able to refresh the access tokens like this :

    ES2015

    const GoogleApis = Meteor.npmRequire('googleapis');
    
    function getAccessToken(user) {
      const googleService = user.services.google;
      // is token still valid for the next minute ?
      if (googleService.expiresAt < Date.now() + 60 * 1000) {
        // then just return the currently stored token
        return {
          access_token: googleService.accessToken,
          token_type: 'Bearer',
          id_token: googleService.idToken,
          expiry_date: googleService.expiresAt,
          refresh_token: googleService.refreshToken,
        };
      }
      // fetch google service configuration
      const googleServiceConfig = Accounts.loginServiceConfiguration.findOne({
        service: 'google',
      });
      // declare an Oauth2 client
      const oauth2Client = new GoogleApis.auth.OAuth2(googleServiceConfig.clientId, googleServiceConfig.secret);
      // set the Oauth2 client credentials from the user refresh token
      oauth2Client.setCredentials({
        refresh_token: user.services.google.refreshToken,
      });
      // declare a synchronous version of the oauth2Client method refreshing access tokens
      const refreshAccessTokenSync = Meteor.wrapAsync(oauth2Client.refreshAccessToken, oauth2Client);
      // refresh tokens
      const tokens = refreshAccessTokenSync();
      // update the user document with the fresh token
      Meteor.users.update(user._id, {
        $set: {
          'services.google.accessToken': tokens.access_token,
          'services.google.idToken': tokens.id_token,
          'services.google.expiresAt': tokens.expiry_date,
          'services.google.refreshToken': tokens.refresh_token,
        },
      });
      //
      return tokens;
    }
    

    Here is a full example of how to refresh your access tokens before using a google service.

    function listMeteorChannel() {
      // fetch a user you want to act on behalf who authorized offline access
      const user = Meteor.users.findOne({
        'services.google.refreshToken': {
          $exists: true,
        },
      });
      if (!user) {
        return;
      }
      const googleServiceConfig = Accounts.loginServiceConfiguration.findOne({
        service: 'google',
      });
      // declare oauth2 client and set credentials
      const oauth2Client = new GoogleApis.auth.OAuth2(googleServiceConfig.clientId, googleServiceConfig.secret);
      // get user access token
      const tokens = getAccessToken(user);
      oauth2Client.setCredentials(tokens);
      // obtain the youtube service at version 3 and perform authentication at service level
      const youtube = GoogleApis.youtube({
        version: 'v3',
        auth: oauth2Client,
      });
      // declare a synchronous version of youtube.channels.list
      const youtubeChannelsListSync = Meteor.wrapAsync(youtube.channels.list, youtube.channels);
      // fetch an info snippet from the Meteor official YouTube channel
      const result = youtubeChannelsListSync({
        part: 'snippet',
        // Meteor channel ID
        id: 'UC3fBiJrFFMhKlsWM46AsAYw',
      });
      result.items.forEach((item) => {
        // display the channel title, which should be 'Meteor'
        console.log(item.snippet.title);
      });
    }
    
    Meteor.startup(listMeteorChannel);
    
    0 讨论(0)
提交回复
热议问题