Google Currently требует, чтобы Вы создали КЛЮЧ API, который характерен для домена того, откуда карта будет вручена. Как Google осуществляет это? Я хочу сделать то же самое.
Я выставляю API для своего сервиса, но хочу позволить клиентам встраивать вызовы в API с помощью JavaScript и не только с сервера. Я мог защитить его только с случайным маркером, но конечно это могло легко имитироваться любым смотрящим на код клиентской машины.
Я всегда понимал это понятие, чтобы не быть возможным, но так или иначе Google делает хорошее задание при осуществлении его.
Редактирование - Это кажется, что Google действительно не сделал ничего удивительного, в конце концов. Их API наиболее вероятен только для отслеживания и не действительно гарантировать, что их API используется человеком с ключом.
Не победитель, но, возможно, есть место для улучшения. Никогда раньше этого не делал. Оригинальная концепция, первый черновик.
#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. Это в конечном итоге происходит медленнее, чем ОС, которая предлагает эти вызовы функций.
Я уверен, что они используют URL-адрес REFERER, чтобы определить, откуда поступает вызов. Если домен не соответствует назначенному ключу, это недопустимый запрос.
В практическом примере, используя PHP, можно проверить домен с помощью $ _ SERVER ['HTTP _ REFERER']
, чтобы проверить указатель. Если домен совпадает, верните допустимый ответ. Если нет, вы можете вернуть несанкционированный ответ 401 или другой ответ.
Сам ключ API, скорее всего, является односторонним хешем домена, с которым связан ключ, и секретом, о котором знает только сервер API Google. Он может содержать некоторые другие части хорошо известной (конечно, для Google) информации. Когда вы делаете запрос из этого домена, сервер API берет домен, из которого исходит запрос, выполняет тот же односторонний расчет хэша и сравнивает два значения.
Для вызовов Ajax они, скорее всего, используют реферер для получения домена узла документа. Хотя реферер может быть подделан, в конечном итоге, чтобы использовать API, вам нужно заставить Google javascript выполняться в документе. На этом этапе этот javascript может проверить, действительно ли документ, вызвавший вызов Ajax API, исходит от целевого сервера. Конечно, это тоже можно подделать, если у вас есть собственная реализация DOM или изменение скрипта «на лету».Однако этот спуфинг должен происходить на стороне клиента, и вероятность того, что веб-сайт, который хочет использовать Google API, сможет подделать клиентское программное обеспечение, довольно мала.
Обратите внимание, что, поскольку API по сути бесплатный, они могли также предложить анонимный доступ к своему API. Очевидно, намерение Google состоит не в защите от несанкционированного доступа к нему, а в том, чтобы гарантировать, что они смогут собрать как можно больше данных об этом использовании данных и иметь возможность связать это использование с другими данными, которые они собрали о целевом домене. Таким образом, я бы не ожидал, что проверка ключа API будет намного сложнее, чем то, что я описал выше - рентабельность инвестиций при более продвинутом подходе слишком низкая.
И, конечно же, есть опасения по поводу возможных XSS-атак через их API. Но я не верю, что их API-ключ слишком сильно привязан к какому-либо анти-XSS-коду, который у них есть.
Простое правило: если свойство помечено как «сохранить», всегда присваивайте ему автоматически освобожденную переменную (если вы создаете его), если, конечно, не НУЖНО также сохранить его в другом месте.
-121--4690680-Я уверен, что они используют URL-адрес REFERER, чтобы определить, откуда поступает вызов. Если домен не соответствует назначенному ключу, это недопустимый запрос.
В практическом примере, используя PHP, можно проверить домен с помощью $ _ SERVER ['HTTP _ REFERER']
, чтобы проверить указатель. Если домен совпадает, верните допустимый ответ. Если нет, вы можете вернуть несанкционированный ответ 401 или другой ответ.
Это работает потому, что нельзя выполнять вызовы API с помощью javascript. Защита браузера запрещает javascript выполнять запросы в любом месте, кроме домена, из которого был создан javascript. Из-за этого любые вызовы API из javascript должны быть возвращены через ваш сервер, где хранится ключ API (ключ api никогда не просматривается javascript).
Почему вы не используете интерфейс 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 для доступа к коду, так как вы не можете проверить эту сторону сервера, я полагаю.
Я согласен со всеми пунктами которые перечислил Франси Пенов. Я хотел бы немного подробнее остановиться на использовании чужого API-ключа. Допустим, вы зарегистрировали key1
на example.com
.
Первая попытка - Если anothersite.com
имеет , Google может проверить его referrer (упомянутая хэш-схема) и в этом случае имеет место несовпадение. Как злой злоумышленник может преодолеть это, поскольку многие люди упоминали, что referrer может быть подделан? Это не совсем применимо в данном случае. Конечно, вы можете послать произвольные заголовки, если вы делаете запрос, но как злой хакер подменит referrer для пользователей на
anothersite.com
? В общем случае это непросто. Были старые версии flash на IE 6, которые позволяли атакующему устанавливать произвольные заголовки при выполнении междоменных запросов, но в целом это не работает для скрипта src
. Я не уверен, делает ли включенный Javascript какую-либо проверку document.location
, чтобы предотвратить это (вероятно, нет).
Вторая попытка - Злой злоумышленник копирует Google Javascript для API-ключа из источника страницы mysite.com
, а затем внедряет измененный Javascript на anothersite.com
. Теперь Google не сможет ничего проверить (удаленный IP будет компьютером пользователя, и вы или Google мало что сможете сделать).
Итак, если вы по какой-то причине хотите сохранить ключ API в тайне (одна из причин - злоумышленник может занести ваш ключ в черный список/заблокировать), то не вставляйте ключ в клиентские и прокси-запросы через ваш сервер (теперь ключ есть в коде вашего приложения).