Synchroniser les droits d'accès des utilisateurs (intégration côté serveur)

Les éditeurs utilisent principalement l'intégration côté serveur pour gérer les lecteurs et leurs droits d'accès. Ils se servent de UpdateReaderEntitlements pour mettre à jour l'enregistrement Google du droit d'accès d'un ID produit pour un PPID.

Configurer l'API dans Google Cloud

La configuration de l'API Subscription Linking dans Google Cloud se fait en deux étapes :

  1. Activer l'API pour un projet donné
  2. Créer un compte de service pour accéder à l'API

Activer l'API Subscription Linking

Pour utiliser un compte de service et gérer les droits d'accès d'un lecteur, l'API Subscription Linking doit être activée et un compte de service OAuth doit être correctement configuré pour un projet Google Cloud. Pour activer l'API Subscription Linking pour un projet, accédez au menu -> API et services -> Bibliothèque et recherchez Subscription Linking, ou accédez directement à la page suivante :


https://console.cloud.google.com/apis/library?project=gcp_project_id

api

Figure 1. Accéder à la bibliothèque d'API et activer l'API pour un projet Google Cloud.

Créer un compte de service

Les comptes de service permettent d'autoriser l'accès à l'API Subscription Linking depuis votre application.

  1. Créez un compte de service dans la console de votre projet.
  2. Créez des identifiants pour le compte de service et enregistrez le fichier credentials.json dans un emplacement sécurisé accessible par votre application.
  3. Accordez le rôle IAM "Administrateur d'associations d'abonnements" au compte de service que vous avez créé. Pour contrôler précisément les fonctionnalités du compte de service, vous pouvez attribuer le rôle approprié en vous référant au tableau ci-dessous.
Fonctionnalité/Rôle Administrateur d'associations d'abonnements Lecteur d'associations d'abonnements Lecteur des droits d'accès aux associations d'abonnements
Obtenir les droits d'accès des lecteurs
Obtenir des lecteurs
Mettre à jour les droits d'accès des lecteurs
Supprimer des lecteurs

Utiliser des comptes de service avec l'API Subscription Linking

Utilisez des comptes de service pour authentifier les appels à l'API Subscription Linking, soit à l'aide de la bibliothèque cliente googleapis, soit en signant les requêtes de l'API REST. Les bibliothèques clientes traitent automatiquement les demandes d'access_token, tandis que l'API REST doit récupérer un id_token pour l'échanger contre access_token.

La bibliothèque cliente et les exemples de l'API REST suivants utilisent le point de terminaison getReader(). Pour voir une démonstration en direct de toutes les méthodes d'API, veuillez consulter le site de démonstration de l'association d'abonnement ou son code.

Exemple de requête avec la bibliothèque cliente Node.js googleapis

import {readerrevenuesubscriptionlinking_v1, Auth} from 'googleapis';
const subscriptionLinking = readerrevenuesubscriptionlinking_v1.Readerrevenuesubscriptionlinking;

class SubscriptionLinking {
  constructor() {
    this.auth = new Auth.GoogleAuth({
      keyFile: process.env.KEY_FILE,
      scopes: [
        'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage'
      ],
    })
  }

  init() {
    return new subscriptionLinking(
        {version: 'v1', auth: this.auth})
  }
}

const api = new SubscriptionLinking();
const client = api.init();

async function getReader(ppid) {
  const publicationId = process.env.PUBLICATION_ID;
  return await client.publications.readers.get({
    name: `publications/${publicationId}/readers/${ppid}`,
  });
};

async function updateEntitlements(ppid) {
  const publicationId = process.env.PUBLICATION_ID;
  const requestBody = {
    /*
    Refer to
    https://developers.google.com/news/subscribe/subscription-linking/appendix/glossary#entitlements_object
    */
    entitlements : [{
      product_id: `${publicationId}:basic`,
      subscription_token: 'abc1234',
      detail: 'This is our basic plan',
      expire_time: '2025-10-21T03:05:08.200564Z'
    }]
  };
  return await client.publications.readers.updateEntitlements({
    name: `publications/${publicationId}/readers/${ppid}/entitlements`,
    requestBody
  });
};

Signer manuellement des requêtes de l'API REST

import fetch from 'node-fetch'
import jwt from 'jsonwebtoken'

function getSignedJwt() {
  /*
    Either store the credentials string in an environmental variable
    Or implement logic to fetch it.
  */
  const key_file = process.env.CREDENTIALS_STRING

  const issueDate = new Date()
  const expireMinutes = 60
  const offsetInSeconds = issueDate.getTimezoneOffset() * 60000
  const expireDate = new Date(issueDate.getTime() + (expireMinutes * 60000))
  const iat = Math.floor((issueDate.getTime() + offsetInSeconds) / 1000)
  const exp = Math.floor((expireDate.getTime() + offsetInSeconds) / 1000)

  const token = {
    iss: key_file.client_email,
    iat,
    exp,
    aud: 'https://oauth2.googleapis.com/token',
    scope:'https://www.googleapis.com/auth/readerrevenue.subscriptionlinking.manage',
  }
  return jwt.sign(token, key_file.private_key, {
    algorithm: 'RS256',
    keyid: key_file.private_key_id,
  })
}

async function getAccessToken(signedJwt) {
  let body = new URLSearchParams();
  body.set('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer')
  body.set('assertion', signedJwt)
  const request = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    body
  })

  const accessResponse = await accessFetch.json()
  return accessResponse.access_token
}

async function getReader(ppid) {
  const publicationId = process.env.PUBLICATION_ID
  const base_url = 'https://readerrevenuesubscriptionlinking.googleapis.com/v1'
  const endpoint = `${base_url}/publications/${publicationId}/readers/${ppid}`
  const signedJwt = await getSignedJwt()
  const accessToken = await getAccessToken(signedJwt)

  const reader = await fetch(endpoint, {
     method: 'GET',
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }).then((response) => {
    return response.json()
  })

  return reader
}