2012-01-01 10 views
1

私はFoursquare APIを読んでいて、場所検索(Googleプレイスの代替)として使用する方法を見つけようとしていました。しかし、クライアントの秘密鍵を常に提供する必要があることに私は驚きました。JavaScriptを使用して四角形の場所を検索し、クライアントの秘密を公開せずに

私はブラウザでそれを使用していますが、応答を取得する唯一の方法は、リクエストにクライアントシークレットとクライアントIDの両方を提供することです。それは "クライアントの秘密"で、クライアントの秘密を使わずにこれを行う別の方法があるはずです。 Google APIは参照URLとクライアントIDをチェックします。 Foursquareはこれをサポートしていますか?

私は私のサーバーでfoursquareに要求を行い、JavaScriptクライアントコードから呼び出すことができます。しかし、ユーザはuser -> foursquare-apiではなく、応答時間が2倍になるのを待たなければならないので、非常に醜い(IMO)でしょう。user -> my-server -> foursquare-api

私のWebアプリケーションで使用するページ:Where can I a great place in the city to see Christmas lights in Boston, MA?を見つけるにはヒントを共有してみてください(実際に投稿する必要はありません)。

+0

私はプロキシソリューションをやっていますが、十分に安全ですが、 'user - > my-server - > foursquare-api'のために遅いです。 –

答えて

1

これは醜いです。しかし、私の2つのセント:

あなたのセキュリティのニーズは、スピードのニーズを大きく上回る場合は、サーバー側のプロキシを使用して...それは基本的に誰もしている、ほとんどのプロキシが一方的に偽装されているか、いくつかの小さなスタンドアローンのレール/エクスプレス/ etcのアプリは、いくつかの既存のアプリケーションのエンドポイントだけで、いくつかのGoogle Appengineを使用していますが、ほとんどの人はプロキシを使用していません。

スピードの必要性がセキュリティの必要性を大きく上回る場合は、キーを公開する「危険な」方法に進みます。 Foursquareからアクセスされたデータから四角形から来ていないユーザーにとって敏感なデータを切り離すほど、それほど悪くはありません。潜在的に偽の地理データや潜在的に偽の場所データを共有しているだけで、あなたは写真を撮ることができます。これはユーザーの財務諸表ではなく、Foursquareという大きなゲームです。さらに悪いことに、APIキーをしばらく変更してください。

IMO、これらのような状況では、中立はないので、あなたの頭の中でバランスをとって、もう一方がもう一方(セキュリティ対スピード)を上回らなければなりません。私は、どちらも本当に正直にも重要であり、何もトレードオフできない状況をまだ見ていません。

+0

ヒント:http://nodejs.org/はサーバーサイドのjavascriptであり、そのような種類のプロキシには、スピードに優れています。 – Quickredfox

2

これは私が同僚の開発者から学んだトリックです。

これはプロキシではありませんが、それと似ています。それでもあなたのIPアドレス(サーバではない)から要求が行われますが、署名はサーバ上で行われます。大規模なネットワークトラフィックは発生しません。

基本的に署名のエンドポイントです。要求を署名するだけで、実際には実行しないページをサーバー上に作成します。 Location: https://api.foursquare.com/...ヘッダーを使用して、ユーザーをページの署名付きバージョンにリダイレクトします。

すべての署名はサーバーで行われますが、実際の要求はクライアントによって行われることに注意してください。シークレットはサーバー上でのみ使用されるため公開されません。

+0

私は同様の手法を見たことがありますが、YQLを使用して呼び出しをプロキシします。あなたはYahooなどのファイルにあなたのキーを格納することができます。私はあなたもcouchdbで何か素敵なことを考え出すことができると確信しています。 – Quickredfox

+0

AFAIK Foursquareは署名されたリクエストをサポートしていません!だから、とにかくクライアントの秘密を公開する必要があります。ヘッダーにあるJSコードのいずれかが表示されますが、もう一方は気づかれる可能性が低くなります。 –

+0

FoursquareはOAuthをサポートしています。だから、上記のアプローチがうまくいくでしょう。 –

0

プロキシのアプローチが本当に助けになりました。私のアプリが埋め込まれた桟橋を実行されていると私は、この問題にアプローチするために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 

あなたのスタックに似たようなものを見つけ出すことができると確信しています。

関連する問題