Как Google Maps защищает их КЛЮЧ API? Как сделать что-то подобным?

Google Currently требует, чтобы Вы создали КЛЮЧ API, который характерен для домена того, откуда карта будет вручена. Как Google осуществляет это? Я хочу сделать то же самое.

Я выставляю API для своего сервиса, но хочу позволить клиентам встраивать вызовы в API с помощью JavaScript и не только с сервера. Я мог защитить его только с случайным маркером, но конечно это могло легко имитироваться любым смотрящим на код клиентской машины.

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

Редактирование - Это кажется, что Google действительно не сделал ничего удивительного, в конце концов. Их API наиболее вероятен только для отслеживания и не действительно гарантировать, что их API используется человеком с ключом.

73
задан hippietrail 19 May 2013 в 01:42
поделиться

5 ответов

C, 99 знаков

Не победитель, но, возможно, есть место для улучшения. Никогда раньше этого не делал. Оригинальная концепция, первый черновик.

#define l w|=*b&b[s]&b[2*s];b+=3/s;s
f(int*b){int s=4,w=0;l=3;l;l;l=2;--b;l=1;b-=3;l;l;return l;}

Спасибо KennyTM за несколько идей и тест-жгут.

«Версия разработки»:

#define l w|=*b&b[s]&b[2*s];b+=3/s;s // check one possible win
f( int *b ) {
        int s=4,w=0; // s = stride, w = winner
        l=3;     // check stride 4 and set to 3
        l;l;l=2; // check stride 3, set to 2
        --b;l=1; // check stride 2, set to 1
        b-=3;l;l; return l; // check stride 1
}
-121--1152344-

Типичные настройки скрипты позволяют много запускать небольшие подпроцессы. В Unix-подобных операционных системах это делается с помощью вызовов функций fork () и exec () , которые имеют очень особую семантику, которую необходимо сохранить (например, копирование на запись общей памяти после форкинга). В Windows подпроцессы создаются с помощью CreateProcess () , который имеет разную семантику (например, полностью отделить пространство памяти от родительского). Для правильного выполнения Unix-подобных скриптов и программ MSYS необходимо проделать большую работу по эмуляции, чтобы создать новые процессы в Windows, такие как fork ()/exec () в Unix. Это в конечном итоге происходит медленнее, чем ОС, которая предлагает эти вызовы функций.

-121--1678519-

Я уверен, что они используют URL-адрес REFERER, чтобы определить, откуда поступает вызов. Если домен не соответствует назначенному ключу, это недопустимый запрос.

В практическом примере, используя PHP, можно проверить домен с помощью $ _ SERVER ['HTTP _ REFERER'] , чтобы проверить указатель. Если домен совпадает, верните допустимый ответ. Если нет, вы можете вернуть несанкционированный ответ 401 или другой ответ.

29
ответ дан 24 November 2019 в 12:24
поделиться

Сам ключ API, скорее всего, является односторонним хешем домена, с которым связан ключ, и секретом, о котором знает только сервер API Google. Он может содержать некоторые другие части хорошо известной (конечно, для Google) информации. Когда вы делаете запрос из этого домена, сервер API берет домен, из которого исходит запрос, выполняет тот же односторонний расчет хэша и сравнивает два значения.

Для вызовов Ajax они, скорее всего, используют реферер для получения домена узла документа. Хотя реферер может быть подделан, в конечном итоге, чтобы использовать API, вам нужно заставить Google javascript выполняться в документе. На этом этапе этот javascript может проверить, действительно ли документ, вызвавший вызов Ajax API, исходит от целевого сервера. Конечно, это тоже можно подделать, если у вас есть собственная реализация DOM или изменение скрипта «на лету».Однако этот спуфинг должен происходить на стороне клиента, и вероятность того, что веб-сайт, который хочет использовать Google API, сможет подделать клиентское программное обеспечение, довольно мала.

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

И, конечно же, есть опасения по поводу возможных XSS-атак через их API. Но я не верю, что их API-ключ слишком сильно привязан к какому-либо анти-XSS-коду, который у них есть.

65
ответ дан 24 November 2019 в 12:24
поделиться

Простое правило: если свойство помечено как «сохранить», всегда присваивайте ему автоматически освобожденную переменную (если вы создаете его), если, конечно, не НУЖНО также сохранить его в другом месте.

-121--4690680-

Я уверен, что они используют URL-адрес REFERER, чтобы определить, откуда поступает вызов. Если домен не соответствует назначенному ключу, это недопустимый запрос.

В практическом примере, используя PHP, можно проверить домен с помощью $ _ SERVER ['HTTP _ REFERER'] , чтобы проверить указатель. Если домен совпадает, верните допустимый ответ. Если нет, вы можете вернуть несанкционированный ответ 401 или другой ответ.

-121--861471-

Это работает потому, что нельзя выполнять вызовы API с помощью javascript. Защита браузера запрещает javascript выполнять запросы в любом месте, кроме домена, из которого был создан javascript. Из-за этого любые вызовы API из javascript должны быть возвращены через ваш сервер, где хранится ключ API (ключ api никогда не просматривается javascript).

-6
ответ дан 24 November 2019 в 12:24
поделиться

Почему вы не используете интерфейс INotifyPropertyChanged и просто запускаете события в классе Monitor, что-то подобное... предположим, что ваши объекты реализуют интерфейс... и каждое свойство в ваших объектах вызывает событие 'PropertyChanged' с параметрами, указывающими значения... в этом пути, это будет пожар и забудет решение вместо того, чтобы закольцовывать список... при вызове instantiate «Monitor» с «RenderWindow», используемым в качестве параметра для «Initialize». Также обратите внимание, что класс «Property» слегка изменен, чтобы включить метод доступа get для возврата объекта, о котором идет речь...

public static class Monitor
{
  private static List monitoredObjects;
  private static RenderWindow _app;

  public static void Initialize(RenderWindow app)
  {
   monitoredObjects = new List();

  }

  public static void Watch(object o)
  {
   monitoredObjects.Add(o);
   o.PropertyChanged += new EventHandler(monitor_PropertyChanged);
  }

  public static void Unwatch(object o)
  {
   o.PropertyChanged -= new EventHandler(monitor_PropertyChanged);
   monitoredObjects.Remove(o);
  }

  public static monitor_PropertyChanged(object sender, PropertyChangedEventArgs e){
    // Not actual code, I actually draw this in game
    Console.WriteLine(e.SomeValue);
  }

  public static void Draw(RenderWindow app)
  {
                    //Not actual code, I actually draw this in game
   foreach (object o in monitoredObjects)
    Console.WriteLine(o.ToString());
  }
 }

 public class Property
 {
  private object obj;
  private PropertyInfo propertyInfo;

  public object PropObj{
     get{ return this.obj; }
  }

  public override string ToString()
  {
   return propertyInfo.Name + ": " + propertyInfo.GetValue(obj, null).ToString();
  }

  public Property(object o, string property)
  {
   obj = o;
   propertyInfo = o.GetType().GetProperty(property);
  }
 }

Надеюсь, что это поможет, С уважением, Том.

-121--4950522-

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

CL-USER> (defun non-destructive ()
           (progn
             (reverse (loop for x from 1 to 100000 collecting x))
             nil))
NON-DESTRUCTIVE
CL-USER> (defun destructive ()
           (progn
             (nreverse (loop for x from 1 to 100000 collecting x))
             nil))
DESTRUCTIVE
CL-USER> (time (non-destructive))
(NON-DESTRUCTIVE) took 140 milliseconds (0.140 seconds) to run 
                    with 2 available CPU cores.
During that period, 156 milliseconds (0.156 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
94 milliseconds (0.094 seconds) was spent in GC.
 1,600,024 bytes of memory allocated.
NIL
CL-USER> (time (destructive))
(DESTRUCTIVE) took 93 milliseconds (0.093 seconds) to run 
                    with 2 available CPU cores.
During that period, 93 milliseconds (0.093 seconds) were spent in user mode
                    0 milliseconds (0.000 seconds) were spent in system mode
63 milliseconds (0.063 seconds) was spent in GC.
 800,024 bytes of memory allocated.
NIL

Итак: Да, избегание консинга может улучшить производительность, но вы должны использовать разрушительную модификацию, только если знаете, что вы делаете. Я бы не сказал, что консинг «медленный» сам по себе, но, тем не менее, избежать его может быть полезно. Если сравнить разницу в выделенной памяти (на что уходит её время), то должно быть понятно, почему вторая версия быстрее первой.

-121--1519689-

Как говорится в моем комментарии:

REFERER является поддельным, поэтому, вероятно, маловероятно, что Google будет использовать его в качестве средства проверки. Смотрите эту запись в википедии.

Я предполагаю, что Google, вероятно, использует IP-адрес вызывающего абонента вместе с DNS-поиском. DNS на самом деле не поддается подделке, так как ваши записи DNS должны быть правильными, чтобы веб-сайт даже дошел до вас.

Но, даже если у этого есть проблемы, потому что если сервер использует установку DNS с циклическим IP-адресом, Google будет перенаправлен на другой IP-адрес при выполнении поиска DNS.

В разделе «Часто задаваемые вопросы»

Обратите внимание, что ключ для http://www.mygooglemapssite.com/ будет принят только при обращении к сайту по этому адресу. Он не будет принят, если доступ к сайту осуществляется по IP-адресу (например, http ://10.1.2.3/) или по имени узла, которое www.mygooglemapssite.com с использованием записи DNS CNAME.

Я предполагаю, что это может быть использование заголовка Host , который отправляется при запросе страницы, что будет работать, как обычно Google просит вас включить его API скрипт непосредственно на страницу. Затем этот сценарий имеет доступ к заголовкам текущей страницы и может использовать их для проверки.

Мое предположение подкреплено тем фактом, что оно не работает для IP-адресов или псевдонимов, а значит, не выполняет проверку DNS.

ЭТОТ метод нельзя подделать, так как он должен быть правильным заголовком для доступа к странице. Однако это означает, что любые псевдонимы домена работать не будут.

Однако это также означает, что вы ДОЛЖНЫ предоставить библиотеку Javascript для доступа к коду, так как вы не можете проверить эту сторону сервера, я полагаю.

3
ответ дан 24 November 2019 в 12:24
поделиться

Я согласен со всеми пунктами которые перечислил Франси Пенов. Я хотел бы немного подробнее остановиться на использовании чужого API-ключа. Допустим, вы зарегистрировали key1 на example.com.

  1. Первая попытка - Если anothersite.com имеет