2016-03-26 12 views
1

私はSteam APIを使用するプログラムを作成しようとしています。 APIキーが含まれているので、クライアントからメソッドの秘密の実際のコードを保持しながら、クライアントからユーザーの情報を取得するメソッドを呼び出すことができるようにしたい。Meteor:クライアントからのアクセス機能、サーバー上で実行

key = 'xxxxxxxxxxxxxxxx'; 

Meteor.steamFunctions = { 
    getName: function(user){ 
     var userSteamId = user.profile.id; 
     Meteor.http.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + key + '&steamids=' + userSteamId, function(error, resultJSON){ 
      if (error){ 
       return 'Error in Steam API'; 
      } else { 
       var json = JSON.parse(resultJSON); 
       return json.personaname; 
      } 
     }) 
    }, 

    getPic: function(user){ 
     var userSteamId = user.profile.id; 
     Meteor.http.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + key + '&steamids=' + userSteamId, function(error, resultJSON){ 
      if (error){ 
       return 'Error in Steam API'; 
      } else { 
       var json = JSON.parse(resultJSON); 
       return json.avatarfull; 
      } 
     }) 
    } 
} 

私は、クライアント側のスクリプトでこのようにそれを呼び出そう:

if (Meteor.isClient){ 
    Template.profile.helpers({ 
     'getName': function(){ 
      return Meteor.steamFunctions.getName(Meteor.user()); 
     } 
    }); 
} 

ただし、

を投げ、私はこのように、サーバーのフォルダにグローバルなどのメソッドを定義してみました

データにアクセスしている最中にユーザーに秘密を保持する方法を教えてください。

答えて

2

まあ、グローバルにMeteorにプロパティを追加するのと同じくらい簡単ではありません。また、これを行うリモートメソッド/呼び出しAPIには、非同期コードが含まれます。

シークレットAPIキーを使用してAPIにコールすると、サーバ側でのみコードがサーバー上に表示されます(例: ./serverサブディレクトリ。クライアント側でMeteor.callで呼び出すことができるサーバー側にMeteor.methodを定義します。

サーバー側のメテオメソッドには、ログインしたユーザーまたはユーザーIDを確認するためにmethod security checksがあり、これを使用して呼び出しを行うか、要求を無視するかを決定できます。要求が不適切であるかエラーがある場合、サーバー側から新しいMeteor.Errorをスローすることができますが、これらは通信するためのリソースを取ります。

メテオールについて理解することは、Javascriptがブラウザやサーバー上でどのように動作するかを変えることは魔法のようなものではないということです。サーバーは最終的にnodejsを実行しています。サーバー上で定義されたオブジェクトは、魔法のようにクライアントに移行したり、逆もありません。オブジェクトが両方に定義されている場合は、実際には2つの別個のコード片です。

したがって、クライアントコードでは、Meteor.callはブラウザからサーバーサイドコードを呼び出すために、実際には非同期の既存のwebsocket APIまたはajax APIを実際に使用しています。これは、ブラウザでコールバック関数を提供して、NameまたはPicを参照する非同期返された結果を処理するためにクライアントコードを構造化する必要があることを意味します。直接リターンと命令的なコーディングスタイルは不可能です。

通常、ルックアップから返された情報の結果として、ユーザーの画面上で何かを更新したいと思うでしょう。通常のMeteorコーディングでは、コールバック関数をsession global variableSession.set()に更新することです。テンプレートはこれらのセッション変数を参照することができ、暗黙的または明示的なTracker.autorun()を介して、APIがデータを返すときに画面を更新できます。

1

は、あなたがする必要がある:

    移動
  1. あなただけのサーバー上で定義されているsteamFunctionsmethodsに。
  2. クライアントから適切にメソッドを呼び出します。

以下は、元の質問に基づくコード例です。これはテストされておらず、微調整が必​​要な場合がありますのでご注意ください。

サーバー/ methods.js

const KEY = 'xxxxxxxxxxxxxxxx'; 
const URL = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002'; 

Meteor.methods({ 
    getName() { 
    const userSteamId = Meteor.user().profile.id; 
    const params = { 
     key: KEY, 
     steamids: userSteamId, 
    }; 

    try { 
     var result = HTTP.get(URL, { params }); 

     // Double check this - I have no idea what this API returns. The value 
     // you want may be nested under result, like result.data or something. 
     return JSON.parse(result).personaname; 
    } catch (e) { 
     // Something bad happened - maybe throw an error. 
     return false; 
    } 
    }, 
}); 

(注)この方法は、サーバー上で定義されているので、私たちはクライアントに私たちのKEYが公開されていません。また、同期バージョンのHTTP APIを使用しているため、値をクライアントに返すことができます。

クライアント/ libに/ user.jsの

Tracker.autorun(function() { 
    user = Meteor.user(); 
    if (user && user.profile && user.profile.id) { 
    Meteor.call('getName', (err, name) => { 
     Session.set('steamName', name); 
    }); 
    } else { 
    Session.set('steamName', ''); 
    } 
}); 

ユーザーログがあるか、更新された、蒸気名を取得し、グローバルセッション変数を設定します。

クライアント/テンプレート/ profile.js

Template.profile.helpers({ 
    getName: function() { 
    return Session.get('steamName'); 
    }, 
}); 

テンプレートで使用するためsteamNameセッション変数をお読みください。

+0

私の問題は今、ユーザーが実際に "ログイン"する前にクライアントから呼び出されているため、 "未定義からアクセスできない"というエラーが出ます。私はwaitOn Meteorを使ってみました。アイロンルータルーターファイルのuser()、私も高速レンダリングをインストールしようとしました...どちらもうまくいかないようです。待機を達成するためのより簡単な方法を知っていますか?いずれにせよ、答えをありがとう、私は本当にそれを感謝します:) –

+0

それは簡単に修正する必要があります。追加する前に、スチーム名がいつ変更されるのか、プロファイルテンプレートがレンダリングされる時期を教えてください。たとえば、名前が変更されず、プロファイルが多くレンダリングされた場合、多くの不要なコールが発生します。その場合は、おそらくグローバルに設定する必要があります。 –

+0

だから私は別の道をやりましたし、実現可能かどうかわからない/正しいものです。私はすべての情報を保持するコレクションを作成することを考えていました。情報はonCreateUser()に挿入され、onLogin()でログインするたびに情報が呼び出され、更新されます。コレクション。しかし、これが最善の方法であるのかどうかは分かりません。それについて意見はありますか?申し訳ありませんが、私はあなたにこれを乗っ取っています...私は物事を行うための最善の方法を知りません:) –

関連する問題