Поиск четырехугольного места с использованием JavaScript без раскрытия тайны клиента - PullRequest
1 голос
/ 01 января 2012

Я читал Foursquare API и пытался найти, как использовать его для поиска мест (в качестве альтернативы Google Places).Однако я был удивлен, что он требует, чтобы секретный ключ клиента предоставлялся всегда! *

Я использую его в браузере, и единственный способ получить ответ - предоставить секретный ключ клиента и идентификатор клиента взапрос.Это «Секрет клиента», должен быть другой способ, без использования секрета клиента.Google API проверяет URL-адрес и идентификатор клиента.Поддерживает ли Foursquare что-то подобное?

Я знаю, что могу сделать запрос на своем сервере к foursquare и вызвать его из моего клиентского кода JavaScript.Но это было бы очень некрасиво (IMO), так как пользователь должен ждать удвоенного времени ответа user -> my-server -> foursquare-api вместо просто user -> foursquare-api.

Страница в моем веб-приложении, которая будет использовать его: Где можноЯ прекрасное место в городе, чтобы увидеть рождественские огни в Бостоне, штат Массачусетс? , попробуйте поделиться советом, чтобы узнать (вам не обязательно его публиковать!).

Ответы [ 3 ]

2 голосов
/ 02 января 2012

Это уловка, которую я узнал от такого же разработчика.

Это не прокси, но похоже. Он по-прежнему будет делать запросы с вашего IP-адреса (не с сервера), но подпись происходит на сервере. Это не создает огромный сетевой трафик.

По сути, это только конечная точка подписи. Вы создаете страницу на своем сервере, которая только подписывает запрос, но фактически не выполняет его. Затем вы используете заголовок Location: https://api.foursquare.com/..., чтобы перенаправить пользователя на подписанную версию страницы.

Обратите внимание, что вся подпись происходит на сервере, но фактический запрос сделан клиентом. Секреты не раскрываются, поскольку они используются только на сервере.

1 голос
/ 02 января 2012

Это ужасно, да. Но мои два цента:

Если ваши потребности в безопасности значительно перевешивают ваши потребности в скорости, то используйте прокси на стороне сервера ... Это в основном то, что делают все, большинство прокси маскируются тем или иным способом, некоторые являются сторонними службами, некоторые являются крошечными автономными приложения rails / express / etc, некоторые являются лишь конечной точкой в ​​вашем существующем приложении, некоторые используют google appengine, но не обманывайте себя, большинство людей используют прокси.

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

IMO, в таких ситуациях нет среднего уровня, вам нужно уравновесить его в своей голове, чтобы одно значительно перевешивало другое (безопасность против скорости). Мне еще предстоит увидеть ситуацию, когда оба они действительно и честно одинаково важны, и ничто не может быть обменено.

0 голосов
/ 27 октября 2014

Прокси-подход действительно помог мне. Мое приложение работает на встроенном причале, и я использовал ProxyServelt для решения этой проблемы:

    import java.net.URI;

    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.ws.rs.core.UriBuilder;

    import org.eclipse.jetty.client.HttpClient;
    import org.eclipse.jetty.client.api.Request;
    import org.eclipse.jetty.proxy.ProxyServlet;
    import org.eclipse.jetty.util.ssl.SslContextFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    public class FoursquareProxyServlet extends ProxyServlet {
        public  static final String FOURSQUARE_API_PREFIX = "foursquare";

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LoggerFactory.getLogger(FoursquareProxyServlet.class);
    private static final String FOURSQUARE_API_VERSION = "20141026";

    private String apiURL;
    private String clientId;
    private String clientSecret;

    public void init() throws ServletException {
        super.init();

        ServletConfig config = getServletConfig();
        apiURL       = config.getInitParameter("foursquare.apiUrl");
        clientId     = config.getInitParameter("foursquare.clientId");
        clientSecret = config.getInitParameter("foursquare.clientSecret");
    }

    @Override
    protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) {
        proxyRequest.getHeaders().remove("Host");
    }

    @Override
    protected URI rewriteURI(HttpServletRequest request) {
        URI uri = UriBuilder.fromUri(this.apiURL)
            .path(request.getRequestURI().replaceAll("/foursquare", ""))
            .replaceQuery(request.getQueryString().trim())
            .queryParam("client_id", this.clientId)
            .queryParam("client_secret", this.clientSecret)
            .queryParam("v", FOURSQUARE_API_VERSION)
            .build();

        return uri;
    }

    protected HttpClient newHttpClient() {
        SslContextFactory sslContextFactory = new SslContextFactory();
        HttpClient httpClient = new HttpClient(sslContextFactory);
        return httpClient;
    }
}

Тогда вам просто нужно подключить его к вашему серверу:

protected ServletContextHandler createFoursquareProxy() {
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/"+FoursquareProxyServlet.FOURSQUARE_API_PREFIX+"/*");

    ServletHolder foursquareProxy = new ServletHolder("foursquare", new FoursquareProxyServlet());
    foursquareProxy.setInitParameter("foursquare.apiUrl", this.foursquareApiUrl);
    foursquareProxy.setInitParameter("foursquare.clientId", this.foursquareClientId);
    foursquareProxy.setInitParameter("foursquare.clientSecret", this.foursquareClientSecret);

    context.addServlet(foursquareProxy, "/*");
    return context;
}

Ваш запрос в этом случае будет выглядеть так:

GET http://{host}:{port}/foursquare/venues/search?&ll=40.7,-74%20&query=sushi

Я уверен, что вы сможете найти что-то похожее с вашим стеком.

...