اجرای مجوز سمت سرور

درخواست‌ها به Gmail API باید با استفاده از اطلاعات کاربری OAuth 2.0 مجاز باشند. هنگامی که برنامه شما نیاز به دسترسی به APIهای Google از طرف کاربر دارد، برای مثال زمانی که کاربر آفلاین است، باید از جریان سمت سرور استفاده کنید. این رویکرد مستلزم ارسال یک کد مجوز یک بار مصرف از مشتری شما به سرور شما است. این کد برای به دست آوردن یک نشانه دسترسی و رفرش توکن برای سرور شما استفاده می شود.

برای کسب اطلاعات بیشتر در مورد اجرای Google OAuth 2.0 در سمت سرور، به استفاده از OAuth 2.0 برای برنامه های وب سرور مراجعه کنید.

فهرست

یک شناسه مشتری و راز مشتری ایجاد کنید

برای شروع استفاده از Gmail API، ابتدا باید از ابزار راه‌اندازی استفاده کنید که شما را از طریق ایجاد پروژه در کنسول API Google، فعال کردن API و ایجاد اعتبارنامه راهنمایی می‌کند.

  1. از صفحه اعتبار، روی ایجاد اعتبار > شناسه مشتری OAuth کلیک کنید تا اعتبارنامه OAuth 2.0 خود را ایجاد کنید یا برای ایجاد یک حساب سرویس، Create credentials > کلید حساب سرویس را انتخاب کنید .
  2. اگر شناسه مشتری OAuth ایجاد کرده اید، نوع برنامه خود را انتخاب کنید.
  3. فرم را پر کنید و روی ایجاد کلیک کنید.

شناسه های مشتری برنامه شما و کلیدهای حساب خدمات اکنون در صفحه اعتبارنامه فهرست شده اند. برای جزئیات، روی شناسه مشتری کلیک کنید. پارامترها بسته به نوع شناسه متفاوت است، اما ممکن است شامل آدرس ایمیل، مخفی مشتری، مبدا جاوا اسکریپت یا URI های تغییر مسیر باشد.

شناسه مشتری را یادداشت کنید زیرا بعداً باید آن را به کد خود اضافه کنید.

رسیدگی به درخواست های مجوز

هنگامی که کاربر برای اولین بار برنامه شما را بارگیری می کند، یک گفتگو برای اعطای مجوز به برنامه شما برای دسترسی به حساب Gmail خود با محدوده های مجوز درخواستی به او ارائه می شود. پس از این مجوز اولیه، تنها در صورتی که شناسه سرویس گیرنده برنامه شما تغییر کند یا محدوده های درخواستی تغییر کرده باشد، گفتگوی مجوز به کاربر ارائه می شود.

احراز هویت کاربر

این ورود اولیه یک شیء نتیجه مجوز را برمی‌گرداند که در صورت موفقیت آمیز بودن، حاوی کد مجوز است.

کد مجوز را با یک نشانه دسترسی مبادله کنید

کد مجوز یک کد یکبار مصرف است که سرور شما می تواند آن را با یک رمز دسترسی مبادله کند. این نشانه دسترسی به Gmail API ارسال می‌شود تا برنامه شما برای مدت محدودی به داده‌های کاربر دسترسی داشته باشد.

اگر برنامه شما نیاز به دسترسی offline دارد، اولین باری که برنامه شما کد مجوز را مبادله می‌کند، همچنین یک نشانه به‌روزرسانی دریافت می‌کند که پس از منقضی شدن رمز قبلی، برای دریافت رمز دسترسی جدید استفاده می‌کند. برنامه شما این توکن به‌روزرسانی را (معمولاً در پایگاه داده روی سرور شما) برای استفاده بعدی ذخیره می‌کند.

نمونه‌های کد زیر مبادله یک کد مجوز برای یک نشانه دسترسی با دسترسی offline و ذخیره رمز رفرش را نشان می‌دهند.

پایتون

مقدار CLIENTSECRETS_LOCATION را با مکان فایل client_secrets.json خود جایگزین کنید.

import logging
from oauth2client.client import flow_from_clientsecrets
from oauth2client.client import FlowExchangeError
from apiclient.discovery import build
# ...


# Path to client_secrets.json which should contain a JSON document such as:
#   {
#     "web": {
#       "client_id": "[[YOUR_CLIENT_ID]]",
#       "client_secret": "[[YOUR_CLIENT_SECRET]]",
#       "redirect_uris": [],
#       "auth_uri": "https://accounts.google.com/o/oauth2/auth",
#       "token_uri": "https://accounts.google.com/o/oauth2/token"
#     }
#   }
CLIENTSECRETS_LOCATION = '<PATH/TO/CLIENT_SECRETS.JSON>'
REDIRECT_URI = '<YOUR_REGISTERED_REDIRECT_URI>'
SCOPES = [
    'https://www.googleapis.com/auth/gmail.readonly',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
    # Add other requested scopes.
]

class GetCredentialsException(Exception):
  """Error raised when an error occurred while retrieving credentials.

  Attributes:
    authorization_url: Authorization URL to redirect the user to in order to
                       request offline access.
  """

  def __init__(self, authorization_url):
    """Construct a GetCredentialsException."""
    self.authorization_url = authorization_url


class CodeExchangeException(GetCredentialsException):
  """Error raised when a code exchange has failed."""


class NoRefreshTokenException(GetCredentialsException):
  """Error raised when no refresh token has been found."""


class NoUserIdException(Exception):
  """Error raised when no user ID could be retrieved."""


def get_stored_credentials(user_id):
  """Retrieved stored credentials for the provided user ID.

  Args:
    user_id: User's ID.
  Returns:
    Stored oauth2client.client.OAuth2Credentials if found, None otherwise.
  Raises:
    NotImplemented: This function has not been implemented.
  """
  # TODO: Implement this function to work with your database.
  #       To instantiate an OAuth2Credentials instance from a Json
  #       representation, use the oauth2client.client.Credentials.new_from_json
  #       class method.
  raise NotImplementedError()


def store_credentials(user_id, credentials):
  """Store OAuth 2.0 credentials in the application's database.

  This function stores the provided OAuth 2.0 credentials using the user ID as
  key.

  Args:
    user_id: User's ID.
    credentials: OAuth 2.0 credentials to store.
  Raises:
    NotImplemented: This function has not been implemented.
  """
  # TODO: Implement this function to work with your database.
  #       To retrieve a Json representation of the credentials instance, call the
  #       credentials.to_json() method.
  raise NotImplementedError()


def exchange_code(authorization_code):
  """Exchange an authorization code for OAuth 2.0 credentials.

  Args:
    authorization_code: Authorization code to exchange for OAuth 2.0
                        credentials.
  Returns:
    oauth2client.client.OAuth2Credentials instance.
  Raises:
    CodeExchangeException: an error occurred.
  """
  flow = flow_from_clientsecrets(CLIENTSECRETS_LOCATION, ' '.join(SCOPES))
  flow.redirect_uri = REDIRECT_URI
  try:
    credentials = flow.step2_exchange(authorization_code)
    return credentials
  except FlowExchangeError, error:
    logging.error('An error occurred: %s', error)
    raise CodeExchangeException(None)


def get_user_info(credentials):
  """Send a request to the UserInfo API to retrieve the user's information.

  Args:
    credentials: oauth2client.client.OAuth2Credentials instance to authorize the
                 request.
  Returns:
    User information as a dict.
  """
  user_info_service = build(
      serviceName='oauth2', version='v2',
      http=credentials.authorize(httplib2.Http()))
  user_info = None
  try:
    user_info = user_info_service.userinfo().get().execute()
  except errors.HttpError, e:
    logging.error('An error occurred: %s', e)
  if user_info and user_info.get('id'):
    return user_info
  else:
    raise NoUserIdException()


def get_authorization_url(email_address, state):
  """Retrieve the authorization URL.

  Args:
    email_address: User's e-mail address.
    state: State for the authorization URL.
  Returns:
    Authorization URL to redirect the user to.
  """
  flow = flow_from_clientsecrets(CLIENTSECRETS_LOCATION, ' '.join(SCOPES))
  flow.params['access_type'] = 'offline'
  flow.params['approval_prompt'] = 'force'
  flow.params['user_id'] = email_address
  flow.params['state'] = state
  return flow.step1_get_authorize_url(REDIRECT_URI)


def get_credentials(authorization_code, state):
  """Retrieve credentials using the provided authorization code.

  This function exchanges the authorization code for an access token and queries
  the UserInfo API to retrieve the user's e-mail address.
  If a refresh token has been retrieved along with an access token, it is stored
  in the application database using the user's e-mail address as key.
  If no refresh token has been retrieved, the function checks in the application
  database for one and returns it if found or raises a NoRefreshTokenException
  with the authorization URL to redirect the user to.

  Args:
    authorization_code: Authorization code to use to retrieve an access token.
    state: State to set to the authorization URL in case of error.
  Returns:
    oauth2client.client.OAuth2Credentials instance containing an access and
    refresh token.
  Raises:
    CodeExchangeError: Could not exchange the authorization code.
    NoRefreshTokenException: No refresh token could be retrieved from the
                             available sources.
  """
  email_address = ''
  try:
    credentials = exchange_code(authorization_code)
    user_info = get_user_info(credentials)
    email_address = user_info.get('email')
    user_id = user_info.get('id')
    if credentials.refresh_token is not None:
      store_credentials(user_id, credentials)
      return credentials
    else:
      credentials = get_stored_credentials(user_id)
      if credentials and credentials.refresh_token is not None:
        return credentials
  except CodeExchangeException, error:
    logging.error('An error occurred during code exchange.')
    # Drive apps should try to retrieve the user and credentials for the current
    # session.
    # If none is available, redirect the user to the authorization URL.
    error.authorization_url = get_authorization_url(email_address, state)
    raise error
  except NoUserIdException:
    logging.error('No user ID could be retrieved.')
  # No refresh token has been retrieved.
  authorization_url = get_authorization_url(email_address, state)
  raise NoRefreshTokenException(authorization_url)

مجوز با اعتبار ذخیره شده

هنگامی که کاربران پس از یک جریان مجوز موفقیت آمیز برای اولین بار از برنامه شما بازدید می کنند، برنامه شما می تواند از یک نشانه تجدید ذخیره شده برای تأیید درخواست ها بدون درخواست مجدد از کاربر استفاده کند.

اگر قبلاً کاربر را احراز هویت کرده‌اید، برنامه شما می‌تواند توکن تازه‌سازی را از پایگاه داده خود بازیابی کند و توکن را در یک جلسه سمت سرور ذخیره کند. اگر رمز بازخوانی باطل شود یا در غیر این صورت نامعتبر باشد، باید این موضوع را درک کرده و اقدام مناسب را انجام دهید.

با استفاده از اعتبارنامه OAuth 2.0

هنگامی که اعتبار OAuth 2.0 همانطور که در بخش قبل نشان داده شده است بازیابی شد، می توان از آنها برای مجوز دادن به یک شی سرویس Gmail و ارسال درخواست به API استفاده کرد.

نمونه سازی یک شیء سرویس

این نمونه کد نشان می‌دهد که چگونه می‌توان یک شیء سرویس را نمونه‌سازی کرد و سپس آن را برای درخواست‌های API مجاز کرد.

پایتون

from apiclient.discovery import build
# ...

def build_service(credentials):
  """Build a Gmail service object.

  Args:
    credentials: OAuth 2.0 credentials.

  Returns:
    Gmail service object.
  """
  http = httplib2.Http()
  http = credentials.authorize(http)
  return build('gmail', 'v1', http=http)

درخواست های مجاز را ارسال کنید و اعتبارنامه های باطل شده را بررسی کنید

قطعه کد زیر از یک نمونه سرویس مجاز Gmail برای بازیابی لیستی از پیام ها استفاده می کند.

اگر خطایی رخ دهد، کد یک کد وضعیت HTTP 401 را بررسی می‌کند که باید با هدایت کاربر به URL مجوز کنترل شود.

بیشتر عملیات Gmail API در مرجع API مستند شده است.

پایتون

from apiclient import errors
# ...

def ListMessages(service, user, query=''):
  """Gets a list of messages.

  Args:
    service: Authorized Gmail API service instance.
    user: The email address of the account.
    query: String used to filter messages returned.
           Eg.- 'label:UNREAD' for unread Messages only.

  Returns:
    List of messages that match the criteria of the query. Note that the
    returned list contains Message IDs, you must use get with the
    appropriate id to get the details of a Message.
  """
  try:
    response = service.users().messages().list(userId=user, q=query).execute()
    messages = response['messages']

    while 'nextPageToken' in response:
      page_token = response['nextPageToken']
      response = service.users().messages().list(userId=user, q=query,
                                         pageToken=page_token).execute()
      messages.extend(response['messages'])

    return messages
  except errors.HttpError, error:
    print 'An error occurred: %s' % error
    if error.resp.status == 401:
      # Credentials have been revoked.
      # TODO: Redirect the user to the authorization URL.
      raise NotImplementedError()

مراحل بعدی

هنگامی که به راحتی درخواست‌های Gmail API را تأیید کردید، آماده شروع به کار با پیام‌ها، رشته‌ها و برچسب‌ها هستید، همانطور که در بخش راهنمای توسعه‌دهندگان توضیح داده شده است.

می‌توانید درباره روش‌های API موجود در مرجع API اطلاعات بیشتری کسب کنید.