Подтвердить что ты не робот

Есть ли способ использовать ключи API для аутентификации в Flask?

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

Есть ли библиотека флагов, которая делает что-то вроде этого? Или есть типичный способ сделать это? Я сделал поиск, и я только натолкнулся на этот, который на самом деле не очень углублен. Я ищу библиотеку, если она есть.

4b9b3361

Ответ 1

Для ключей аутентификации создайте случайное значение и сохраните это значение в базе данных. random() обеспечивает недостаточную энтропию для таких вещей, поэтому используйте os.urandom().

Ссылка, которую вы опубликовали, имеет очень хороший пример того, как обрабатывать вещи с помощью функции декоратора. В функции декоратора проверьте, что в запросе установлено значение appkey, убедитесь, что оно действительно в базе данных, а затем верните функцию. Если приложение недействительно, raise AuthenticationError("Invalid appkey") и все готово.

Пример, с которым вы связаны, немного запутан. Мне нравится демонстрация из Как сделать цепочку декораторов функций? лучше.

def checkAppKey(fn):
    def inner(*args, **kwargs): #appkey should be in kwargs
        try:
            AppKey.get(appkey)
        except KeyError:
            raise AuthenticationError("Invalid appkey")
            #Whatever other errors can raise up such as db inaccessible
        #We were able to access that API key, so pass onward.
        #If you know nothing else will use the appkey after this, you can unset it.
        return fn(*args, **kwargs)
    return inner

Ответ 2

Вот функция, которая использует hashlib, который работал достаточно хорошо для меня:

def generate_hash_key():
    """
    @return: A hashkey for use to authenticate agains the API.
    """
    return base64.b64encode(hashlib.sha256(str(random.getrandbits(256))).digest(),
                            random.choice(['rA', 'aZ', 'gQ', 'hH', 'hG', 'aR', 'DD'])).rstrip('==')

Возможное решение для реализации этого приложения может быть применено на каждом из маршрутов, которые вы хотите защитить.

Пример:

def get_apiauth_object_by_key(key):
    """
    Query the datastorage for an API key.
    @param ip: ip address
    @return: apiauth sqlachemy object.
    """
    return model.APIAuth.query.filter_by(key=key).first()

def match_api_keys(key, ip):
    """
   Match API keys and discard ip
   @param key: API key from request
   @param ip: remote host IP to match the key.
   @return: boolean
   """
   if key is None or ip is None:
      return False
   api_key = get_apiauth_object_by_key(key)
   if api_key is None:
      return False
   elif api_key.ip == "0.0.0.0":   # 0.0.0.0 means all IPs.
      return True
   elif api_key.key == key and api_key.ip == ip:
      return True
   return False

def require_app_key(f):
   """
   @param f: flask function
   @return: decorator, return the wrapped function or abort json object.
   """

   @wraps(f)
   def decorated(*args, **kwargs):
      if match_api_keys(request.args.get('key'), request.remote_addr):
         return f(*args, **kwargs)
      else:
         with log_to_file:
            log.warning("Unauthorized address trying to use API: " + request.remote_addr)
         abort(401)
      return decorated

И тогда вы можете использовать декоратор как таковой:

@require_app_key
def delete_cake(version, cake_id):
   """
   Controller for API Function that gets a cake by ID
   @param cake_id: cake id
   @return: Response and HTTP code
   """

В этом примере SQLAlchemy хранит ключи в базе данных (вы можете использовать SQLite).

Вы можете увидеть реализацию здесь: https://github.com/haukurk/flask-restapi-recipe.

Ответ 3

"Типичным" способом генерации ключа API является создание UUID (обычно путем создания хеша md5 некоторого подмножества информации пользователя + несколько случайной информации (например, текущего времени)).

Все ключи API, однако, должны быть UUID. Шестнадцатеричный хэш, созданный md5, отвечает этому требованию, но есть и другие методы.

Как только вы создали ключ для пользователя, сохраните его в базе данных как часть пользовательской информации и убедитесь, что их ключ (обычно хранящийся в файле cookie) соответствует тому, что у вас есть. Фактическая механика этого (несколько) описана на странице, с которой вы связаны.