Статьи

Мобильные игры: создание службы токенов безопасности с помощью службы хранения объектов

Эта статья была первоначально опубликована на Alibaba Cloud . Спасибо за поддержку партнеров, которые делают возможным использование SitePoint.

Думаете, у вас есть лучший совет по лучшему использованию облачных сервисов Alibaba? Расскажите нам об этом и воспользуйтесь своим шансом выиграть Macbook Pro (плюс другие интересные вещи). Узнайте больше здесь .

В мобильных играх многие приложения требуют от разработчиков разделения ресурсов игроков. Это включает в себя ряд вещей, от сохранения файлов до обработки информации профиля пользователя. Используя традиционные методы, разработчики могут управлять этим разделением, но должны учитывать многие другие проблемы, такие как безопасность, масштабируемость и API.

По мере развития облачных технологий растет потребность в удобстве и функциональности более высокого уровня. С помощью Object Storage Service ( OSS ) клиенты могут легко и эффективно хранить свои объекты и управлять ими. OSS предоставляет сервис обработки изображений в режиме реального времени. Некоторым клиентам могут потребоваться дополнительные функции, такие как предоставление пользователям ограниченного доступа к таким услугам, как OSS, но с удобством безопасного централизованного управления.

Служба маркеров безопасности обеспечивает краткосрочное управление правами доступа для учетных записей Alibaba Cloud или пользователей оперативной памяти. С помощью STS вы можете выдавать федеративным пользователям, которые управляются в вашей локальной системе учетных записей, учетные данные для доступа, которые настраивают срок действия и разрешение на доступ. Федеративные пользователи могут использовать учетные данные временного доступа STS для прямого вызова API службы Alibaba Cloud или для входа в консоль управления Alibaba Cloud для доступа к проверенным ресурсам.

В этом сценарии мы проверяем функциональность STS с помощью OSS.

Предпосылки

Требуется возможность настроить параметры управления доступом к ресурсам (ОЗУ) и роли. Для получения дополнительной информации см. Роли .

Пример кода написан на Python. Хотя это и не требуется, базовое понимание компьютерного программирования является преимуществом. Пример кода, представленный в этом руководстве, может служить шаблоном, который можно изменить в соответствии с вашими потребностями. Многие люди в настоящее время используют сырой API для управления средой или приложением. Хотя SDK доступен на многих языках, сырой API обеспечивает большую гибкость.

Архитектура

На этой схеме пользователь ОЗУ хочет загрузить изображения в отдельную папку в корзине OSS .

Процесс загрузки выглядит следующим образом:

  1. Пользователь принимает на себя роль ОЗУ для чтения и записи OSS Access для определенной папки в Alibaba Cloud, вызывая AssumeRole.
  2. STS возвращает набор временных учетных данных безопасности.
  3. Пользователь применяет временные учетные данные для доступа к OSS. Затем пользователь может сделать вызов для чтения или записи объекта.

Мы берем OSS в качестве примера здесь. Однако STS может использоваться для предоставления временного доступа к широкому спектру облачных сервисов Alibaba. В этом руководстве мы используем детализированное разрешение STS, чтобы ограничить доступ к определенной корзине OSS.

Реализация

В примере кода три файла:

  • sts.py
    • Это код для принятия роли и для получения важной информации, такой как accessKeyId, accessKeySecret и securityToken.

Доступны следующие функции:

  • Генерируйте подписи, чтобы гарантировать подлинность запроса
  • Получать HTTPS-запросы

Пример кода для файла «sts.py» выглядит следующим образом:

from base64 import b64encode
from datetime import datetime
from Crypto.Hash import SHA, HMAC
import md5, httplib, urllib, uuid, json
##### CONFIG MANAGEMENT
accessKeyId = "<access_key_id>"
accessKeySecret = "<access_key_secret>"
##### FUNCTION MANAGEMENT
def generateSignature(accessKeySecret, stringToSign):
    hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
    return b64encode(hmac.digest())
def getHttpsRequest(host, verb, path):
    conn = httplib.HTTPSConnection(host)
    conn.request(verb, path)
    return conn.getresponse()
# ###### STS MANAGEMENT
host = "sts.aliyuncs.com"
verb = "GET"
bucketName = "<bucket_name>"
folderName = "1"
policy = '{"Statement": [{"Effect": "Allow","Action": ["oss:*"],"Resource": ["acs:oss:*:*:' + bucketName + '/' + folderName + '","acs:oss:*:*:' + bucketName + '/' + folderName + '/*"]}],"Version": "1"}'
dictionaryParams = {
    "AccessKeyId": accessKeyId,
    "Action": "AssumeRole",
    "DurationSeconds": "3600",
    "Format": "JSON",
    "Policy": policy,
    "RoleArn": "acs:ram::5081099437682835:role/ramtestossreadwrite",
    "RoleSessionName": "<session_name>",
    "SignatureMethod": "HMAC-SHA1",
    "SignatureNonce": str(uuid.uuid1()),
    "SignatureVersion": "1.0",
    "Timestamp": datetime.strftime(datetime.utcnow(), "%Y-%m-%dT%H:%M:%SZ"),
    "Version": "2015-04-01"
}
stringToSign = ""
for key in sorted(dictionaryParams.iterkeys()):
    value = urllib.quote(dictionaryParams[key], safe="")
    if stringToSign != "":
        stringToSign += "&"
    stringToSign += key + "=" + value
stringToSign = verb + "&%2F&" + urllib.quote(stringToSign)
signature = generateSignature(accessKeySecret + "&", stringToSign)
dictionaryParams["Signature"] = signature
params = urllib.urlencode(dictionaryParams)
path = "/?" + params
response = getHttpsRequest(host, verb, path)
if response.status == 200:
    jsonData = json.loads(response.read())
    print "Copy paste the respective information to file ossrest.py\n"
    print "accessKeyId: " + jsonData['Credentials']['AccessKeyId']
    print "accessKeySecret: " + jsonData['Credentials']['AccessKeySecret']
    print "securityToken: " + jsonData['Credentials']['SecurityToken']
  • ossrest.py
    • Это код для загрузки и удаления объекта.

Доступны следующие функции:

  • Генерировать подписи
  • Генерировать заголовки
  • Делать HTTP-запросы
  • Загрузить объекты
  • Удалить объекты

Пример кода для файла «ossrest.py» выглядит следующим образом:

 from base64 import b64encode
from datetime import datetime
from Crypto.Hash import SHA, HMAC
import md5, httplib, urllib, uuid
##### MAIN CONFIG (STS)
accessKeyId = "<access_key_id>"
accessKeySecret = "<access_key_secret>"
securityToken = "<security_token>"
##### FUNCTION MANAGEMENT
def generateSignature(accessKeySecret, stringToSign):
    hmac = HMAC.new(accessKeySecret, stringToSign, SHA)
    return b64encode(hmac.digest())
def generateHeaders(verb, canonicalizedResource = "/", canonicalizedOSSHeaders = {}, signature = {}):
    # authorization
    stringToSign = verb + "\n"
    if "content" in signature:
        stringToSign += md5.new(signature["content"]).digest()
    stringToSign += "\n"
    if "content_type" in signature:
        stringToSign += signature["content_type"]
    stringToSign += "\n"
    date = datetime.strftime(datetime.utcnow(), "%a, %d %b %Y %H:%M:%S GMT")
    stringToSign += date + "\n"
    if len(canonicalizedOSSHeaders):
        for index, value in canonicalizedOSSHeaders.items():
            stringToSign += index.lower() + ":" + value + "\n"
    stringToSign += canonicalizedResource
    signature = generateSignature(accessKeySecret, stringToSign)
    # headers
    headers = {"Date": date, "Authorization": "OSS " + accessKeyId + ":" + signature}
    headers.update(canonicalizedOSSHeaders)
    return headers
def sendHttpsRequest(host, verb, headers, path = "/", params = ""):
    conn = httplib.HTTPSConnection(host)
    conn.request(verb, path, params, headers)
    return conn.getresponse()
##### OBJECT MANAGEMENT
canonicalizedOSSHeaders = {"x-oss-acl": "public-read", "x-oss-security-token": securityToken}
bucketName = "<bucket_name>"
host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
hostMain = "oss-ap-southeast-1.aliyuncs.com"
folderName = "1"
fileName = "<filename>"
### UPLOAD OBJECT
verb = "PUT"
canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName, open(fileName, "rb"))
print "Successfully uploaded " + fileName + " object to " + bucketName + "/" + folderName + " bucket/folder."
print response.status, response.reason
print response.read()
### DELETE OBJECT
verb = "DELETE"
canonicalizedResource = "/" + bucketName + "/" + folderName + "/" + fileName
headers = generateHeaders(verb, canonicalizedResource, canonicalizedOSSHeaders)
response = sendHttpsRequest(host, verb, headers, "/" + folderName + "/" + fileName)
print "Successfully deleted " + fileName + " object."
print response.status, response.reason
print response.read()
  • other_sample.py
    • Это код для других сценариев. Эти образцы не могут быть непосредственно применимы к STS, но представлены в качестве примеров.

Доступны следующие функции:

  • Создать ведра
  • Список ведер
  • Загрузить объекты
  • Список объектов
  • Удалить объекты
  • Удалить ведра

Пример кода для файла «other_sample.py» выглядит следующим образом:

 bucketName = "<bucket_name>"
host = bucketName + ".oss-ap-southeast-1.aliyuncs.com"
fileName = "<file_name>"
### CREATE BUCKET
verb = "PUT"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully created " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### LIST BUCKET
host = "oss-ap-southeast-1.aliyuncs.com"
verb = "GET"
signature = {}
canonicalizedResource = "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully listed buckets."
print response.status, response.reason
print response.read()
### UPLOAD OBJECT
verb = "PUT"
signature = {}
canonicalizedResource = "/" + bucketName + "/" + fileName
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers, "/" + fileName, open(fileName, "rb"))
print "Successfully uploaded " + fileName + " object to " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### LIST OBJECT
verb = "GET"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully listed objects in " + bucketName + " bucket."
print response.status, response.reason
print response.read()
### DELETE OBJECT
verb = "DELETE"
signature = {}
canonicalizedResource = "/" + bucketName + "/" + fileName
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers, "/" + fileName)
print "Successfully deleted " + fileName + " object."
print response.status, response.reason
print response.read()
### DELETE BUCKET
verb = "DELETE"
signature = {}
canonicalizedResource = "/" + bucketName + "/"
headers = generateHeaders(verb, signature, canonicalizedResource, canonicalizedOSSHeaders)
response = sendRequest(host, verb, headers)
print "Successfully deleted " + bucketName + " bucket."
print response.status, response.reason
print response.read()

Ожидаемые ответы следующие:

sts.py

ossrest.py

Вывод

Этот пример фокусируется на OSS , но сервис STS также может использоваться для управления доступом к другим облачным сервисам Alibaba. Вариант использования, который мы описываем в этом руководстве, — игра. Другие сценарии или услуги, которые требуют краткосрочного доступа к OSS, могут включать:

  • Веб-приложения
  • Мобильные приложения

Дополнительная информация