10

サーバー上の Web サイトからデータを読み込むために REST API を使用する PhoneGap に組み込まれた単純なアプリを作成しています (PhoneGap 内で PHP を実行できないため)。

一部のデータをリストする例は次のとおりです。

$.ajax({
    url: 'http://myserver.com/posts/index.json',
    dataType: 'jsonp',
    success: function(data) {
        for (var i=0,total=data.length; i<total; i++)
        { 
            console.log(data.Post.title[i]);
        }
    }
});

これで問題なく、返されたデータを PhoneGap アプリで使用できます。ただし、投稿リストにログインする必要があるとしましょう...

これをどのように処理しますか?ログインフォームにリダイレクトする通常の認証リクエストとは異なり、私の JSON の世界ではこれは起こらないからです。実際、実際の HTML ログイン フォームが返され、JavaScript が HTML ではなく JSON を想定しているため、エラーが発生します。

認証が要求された場合、現在行っているようにアプリから HTML ログイン フォームを返すのではなく、PhoneGap アプリにログイン フォーム ビューをロードするなど、これを処理するためのベスト プラクティスはありますか? おそらくJSON経由で認証リクエストを送信しますか?

例として、JSON 化された単純なメソッドは次のようになります。

public function index() {
    $this->set('posts', $this->paginate());
    $this->set('_serialize', array('posts'));
}

前述のように、メソッド名を に渡さないbeforeFilterようにすることで、 でこのメソッドを保護できます。したがって、リクエストが JSON であるかどうかを知るために beforeFilter で巧妙なことをする必要があると推測しています。そうであれば、メソッドに認証が必要かどうかを確認し、そうであればエラーを送り返します (通常は Cake のような HTML フォームではなく)。 JSON で AuthComponent を介して行うか、アクセスを許可します。$this->Auth->allow()

更新: 2012 年 1 月 13 日

このテーマについてさらに調査を行った後、RESTful API に関して私が構築しようとしているものを効果的に構築しているように見えるため、Forrst API を調べました。

たとえば、次のような呼び出しがあります: https://forrst.com/api/v2/post/comments?tiny_id=HUDこれは基本的に、HUD の小さな ID を持つ投稿のコメントを表示すると言っています。認証されていない場合に返されるものは次のとおりです。

{"resp":{"error":"this method requires authentication"},"stat":"fail","in":0.0903,"authed":false,"authed_as":false,"env":"prod"}

ここで興味深いのは、Forrst にログインしている場合でも、実際の要求を認証するために何らかのトークンを期待しているのではなく、セッションを見ていないため、そのエラー メッセージが表示されることです。例えば?access_token=550e8400-e29b-41d4-a716-446655440000

ここでの主な質問は、どうすればこれを Cake アプリに組み込むことができるかということです。計画は次のとおりです。

私のアプリでは、AJAX 経由でリクエストしたかブラウザでリクエストしたかに関係なく、ログイン ページにリダイレクトされます。Forrst は両方を処理し、API を呼び出すと常に JSON エラーを返し、HTML を返すことはありません! これが私の実装で達成したいことです。ユーザー テーブルに access_token 列を追加しました (セキュリティ上の理由から、誰かがパスワードを更新するたびに変更されます)。次のステップは、A) 保護されたメソッドのこのアクセス トークンをチェックし、それが正しい場合は許可または拒否します。次に、B) トークンが存在しないか正しくない場合に何らかの方法で処理し、HTML ログインの代わりに正しいエラー ステータスを送信する必要があります。形。

4

5 に答える 5

4

Phonegap にも組み込まれたアプリケーション (現在は Cordova と呼ばれています) にも同じ問題がありました。認証を機能させるのは本当に苦労しましたが、最終的には Facebook API を使用して機能させることができましたが、Facebook を使用したくないと思います。

したがって、次のコードを実行して、XMLHttpRequest であるかどうかを確認するだけです。

PostsController - index()

if ($this->RequestHandler->isAjax() == 1){
    // This is an Ajax call
    $this->layout = 'json';
    $this->set('data', array('data', 'to', 'parse'));
} else {
    // This is the normal request
    # do the stuff you want to do here as usual
}

ただし、これはログインを要求するため、リストにないため、ログインしない限りそこに到達することさえできません。したがって、最初のリクエストを処理$this->Auth->allow()する新しいを作成する必要があります。AjaxController上記のコードを に挿入してbeforeFilter、そこから魔法をかけてください。そこから、誰かがログインしているかどうか、およびユーザーの現在の状態を簡単に確認できます。彼がログインしていて、データを返したい場合。必要なモデルを呼び出すかrequestAction('/path/to/what/i/need')、Ajax 呼び出しで送信したポスト変数で必要なパスを宣言できるコントローラー関数を呼び出すことができます。

では、正しく解析されるものを に伝えるajax layoutことができます。json_encode$data

アプリ

JavaScript で、いくつかのデータを取得します。返された JSON 文字列を次のキーで構成するとします:statusdata.

status返された JSON でが設定されているとしましょうauth。認証が必要であることがわかっているので、すべてを処理するログイン フォームを表示できます。アプリで素敵なログインビューを作成するだけで、そのすべての側面を制御でき、うまくいけばより安全になります.

statusが設定されている場合はsuccess、それに応じてすべての投稿を表示できます。

独自の API をどのように作成したかを示す別のトピックへの回答があります

警告JavaScript は Phonegap アプリケーションで安全に使用できるように見えますが、そうではありません! 誰でも、Android デバイスから .apk ファイルをダウンロードして で開くことがAndroid emulatorでき、すべての JavaScript および HTML コードを表示できます。そのため、JavaScript に直接コーディングするデータと、API へのアクセス方法には十分注意してください。


私の答えはちょっと漠然としていることを知っているので、この答えに関する追加情報が必要な場合は、お尋ねください!

于 2013-01-14T16:28:53.217 に答える
2

うまくいけば、これでうまくいくでしょう:

このコード スニペットは、名前付きパラメーターを とともに使用しis('ajax')て json 要求を決定し、ユーザーがまだログインしていないかどうかも確認します。次に、要求されたアクションに認証が必要な場合にのみ json エラーを送信します。

まず、これを in に入れbeforeFilter()ますAppController:

//see if request is json (json is sent by adding a named param e.g. posts/index/json:1
//if so also check that user not already logged in
if (!empty($this->params['named']['json']) && $this->request->is('ajax') &&  !$this->Auth->user())
{
    //see if the action needs authentication
    $requiresAuth = !in_array($this->params['action'], $this->Auth->allowedActions);
    if ($requiresAuth)
    {
        //send json response
        $response = array('error' => 
            array(
                'code' => 123,
                'message' => 'authError',
            )
        );
        echo json_encode($response);
        exit;
    }
}

リクエスト json を作成する/json:1には、パスに追加します (たとえばhttp://myserver.com/posts/index/json:1、名前付きの $_GET パラメータとして)。各コントローラーで、 を呼び出す前にbeforeFilter()、まず許可されたアクションを に追加してください。$this->Auth->allow parent::beforeFilter()

Access Control Lists (ACL) でより高度な認証を使用している場合は、http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.htmlを参照してください。アクションが ACL で許可されている場合:

//the group_id to check permission for (must exist)
$group_id = 8; //your group_id
$group = array(
    'model' => 'Group',
    'foreign_key' => $group_id
);
$actionPath = $this->name . '/' . $this->params['action'];
$requiresAclAuth = $this->Acl->check($group, $actionPath);

ACL に認証が必要かどうかを確認するには:

if ($requiresAclAuth && $requiresAuth)
{
    //send json response
    //...
}
于 2013-01-16T16:41:42.033 に答える
2

これから理解できることは、ユーザーがログインしていない場合、login required のようなエラー メッセージを json 形式で返す何らかの方法が必要だということです。できることは、次のような関数を作成できることです。

    public function index ($token=NULL)
{
  if($token != NULL)
  {
   // call some method to check if token is valid
   // do required processing 
  }
  else
{
  $response=array('response'=>'failure','message'=>'Login required');
  echo json_encode($response);
}  

ajax 呼び出しの場合:

 url: 'http://myserver.com/posts/index.json/'+token;

ユーザーテーブルでは、ユーザー登録時に単純にいくつかのアクセストークンを生成し、それを「アクセストークン」という列に保存します。

このトークンは、ユーザーがログインしたときに返されます。

したがって、リクエストの送信中にそれを ajax 呼び出しに追加できます。

ajax 呼び出しhttp://yourdomain.com/posts/showPostsの投稿コントローラーで showPosts メソッドを言ってから 、

$method=$this->action; //this fetches the name of the method called                                                   
$Mmethods =array('showPosts','test2'); // methods requiring login                                                               
if(in_array($method,$Mmethods)) {                                  
$this->params array will give you all the parameters passed in URL.
//Fetch the access token from this array if it is set in 'url' index //of this array.                          
//if token is found, run sql query whether it exists in database or //not, else return response with errors and exit;}
于 2013-01-11T11:46:42.973 に答える
2

明確化の理由: ユーザーが返された投稿を表示するには、常に「ログイン」する必要がありますか? それとも、一部の投稿のみがユーザーのログインを必要としますか? 反対側のスクリプトを制御できます(index.json)か?

私の理解では、PhoneGapアプリのページを使用して「ログイン」し、サーバーへのリクエストとともに情報を保存して送信するindex.jsonか、適切な文字列を処理して返すことができるphpスクリプトを使用しjsonます。基本的に、一般的なブラウザでセッション Cookie がどのように機能するか。

別のオプションは、PhoneGap でキャッチ、読み取り、処理できるメッセージを含む文字列をindex.json返すように を変更しjson、必要に応じてアプリ内でユーザーにログイン フォームを表示し、上記の段落と同じことを行うことです。

コードと例を喜んでお手伝いしますが、現在の投稿は、現在のコードとサーバーから返されるものについて漠然としています。

于 2013-01-12T22:33:23.343 に答える
1

jQuery ajax()関数を使用すると、ユーザー名:とパスワード:(http://api.jquery.com/jQuery.ajax/)を使用して、リクエストとともにログイン情報を渡し、これらを使用して、エラー:

于 2013-01-11T11:35:43.213 に答える