web-dev-qa-db-ja.com

Drupalサービス3ログインとCSRF

Phonegapアプリ(JS)で作業していて、リクエストでCSRFトークンを渡す方法がわかりません。最初にuser/login.jsonを呼び出してからトークンを保存する必要がありますか?今後のリクエストでは、トークンをプルするにはどうすればよいですか?

$('#page_dashboard').live('pageshow',function(){
  try {
    // Obtain session token.
    $.ajax({
        url:"http://" + website + "/?q=my_services/user/token.json",
        type:"post",
        dataType:"text",
        error:function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        },
        success: function (token) {
        // Call system connect with session token.
        $.ajax({
      url:"http://" + website + "/?q=my_services/system/connect.json",
      type: "post",
      dataType: "json",
      beforeSend: function (request) {
        request.setRequestHeader("X-CSRF-Token", token);
      },
      error: function (jqXHR, textStatus, errorThrown) {
        alert(errorThrown);
      },
      success: function (data) {
        var drupal_user = data.user;
        if (drupal_user.uid == 0) { // user is not logged in, show the login button, hide the logout button
            $('#button_login').show();
            $('#button_logout').hide();
            $('#button_create').hide();
        }
        else { // user is logged in, hide the login button, show the logout button
            document.getElementById("welcome").innerHTML = "<center>Welcome " + drupal_user.name + "</center>";
            $('#button_login').hide();
            $('#button_logout').show();
            $('#button_create').show();
        }
      }
    });
        }
    });
  }
 catch (error) { alert("page_dashboard - " + error); }
});
3
Ken J

Drupal RESTfulサービスに関するドキュメントや一般情報が不足していることに驚いています。

最良のリソースは Drupalgap の作成者でありメンテナーである Tyler Frankenstein からです。私が彼の記事 here から始めたとき、タイラーに感謝します。残念ながら、ドキュメントはかなり古く、現在のバージョンのサービスでは動作しません。

シンプルなサイトをAndroid/IOSアプリに配置しようとしている初心者には、Drupalgapを強くお勧めします。それはよく維持され、絶えず成長している素晴らしいツールです。

言われていることは.... Drupalgapは素晴らしいですが、最終的にはフレームワークの要件(つまり、Drupal)を超えて拡張する機能が必要です。 JavaScriptがRESTfulサービスとどのように相互作用するかを理解することが、そのポイントの鍵となります。多大な努力の末、私はようやくさまざまなソースからのデータをまとめ、解決策を考え出しました。これでうまくいったことを覚えておいてください。これを行うにはもっと良い方法があると確信していますが、私はこれを知っているだけです。

Drupal 7&Services 3.5 +で接続するPhoneGapアプリを作成する

私の環境:

Ubuntu 14.04
Cordova 3.5
Android SDK Manager 23
Apache 2.4.7
Drupal 7.28
Services 7.x-3.7
JQuery 1.11.1
jQuery Mobile 1.4.3

1)環境をセットアップします

Apache、Drupal、Phonegapなどをインストールします。drupal=サブディレクトリ(localhost/drupal)にインストールしました。サービスエンドポイントをセットアップし、リソースを有効にしてください。cordovaを使用して、私のPhonegapアプリの足場:

 cordova create MyApp
 cd MyApp
 cordova platform add Android
 cordova build

私のphonegap wwwフォルダーからApacheルートへのシンボリックリンクがあるので、展開する前にブラウザーでモバイルアプリをテストできます。

2)テスト用にCORSを有効にします

JavaScriptコンソールは開発者に実際にコードで何が起こっているかについてのより多くの洞察を与えるので、ローカルでのテストは大きな要件です。 CoRSを有効にすることは、テストを機能させるための要件でした。 CORSを適切に機能させるのは苦痛でした。私はローカルサーバー(localhost)からテストしており、CORSが一致するように構成されていることに注意してください。それに応じて構成を更新します。

1. Enable mod-headers,mod-setenvif
2. Add:
    Header add Access-Control-Allow-Origin "*"
   to the Apache Directory Directives (example.conf)
3. Add:
    SetEnvIf Origin "^(https?://localhost|https://[a-z]+\.my\.base\.domain)$" Origin_SUB_DOMAIN=$1
    Header set Access-Control-Allow-Origin: "%{Origin_SUB_DOMAIN}e" env=Origin_SUB_DOMAIN
    Header set Access-Control-Allow-Methods "GET, PUT, POST, OPTIONS"
    Header set Access-Control-Allow-Credentials "true"
    Header set Access-Control-Allow-Headers "Authorization, Origin, Content-Type, X-CSRF-Token"
   to the .htaccess file at the root of your Drupal installation 
4. Reload/restart Apache

3)jQuery Mobileアプリを作成します私はタイラーの最初の指示に従い、jQuery Mobileを使用してアプリケーションを開発しました。 JavaScriptは、サービス発行キューの投稿 here から取得されました。これは非常に基本的なアプリです-ログインしてユーザー名を出力するだけです...しかし、トークンが渡される方法を理解したら、これを拡張して任意のリクエストを実行できます。

これが私のindex.htmlファイルです:

<!DOCTYPE html>
<html>
    <head>
    <title>Hello World</title>
        <script src="js/jquery.min.js"></script>
        <link rel="stylesheet" href="css/jquery.mobile.css" />
        <script src="js/jquery.mobile.js"></script>
    </head>
    <body>
        <div data-role="page" id="page_dashboard"><!-- page -->
            <script type="text/javascript" charset="utf-8" src="script.js"></script>
            <div data-role="header"><h1>Home</h1></div>
            <div data-role="content"><!-- content -->
                <h2 align="center">Shopping List App</h2>
                <p id="welcome"></p>
            </div>
            <div>
                <label for="page_login_username">My Name</label>
                <input type="text" id="page_login_username" />
            </div>
            <div>
                <label for="page_login_name">Username</label>
                <input type="text" id="page_login_name" />
            </div>
            <div>
                <label for="page_login_pass">Password</label>
                <input type="password" id="page_login_pass" />
            </div>
            <input type="text" id="page_login_token" />
            <input type="hidden" id="page_login_session_ID" />
            <input type="hidden" id="page_login_session_name" />
            <fieldset>
                <div><button type="button" data-theme="b" id="page_login_submit">Login</button></div>
            </fieldset>
  </div>
        </div> <!-- end page -->
    </body>
</html>

これが私のscript.jsファイルです:

$(document).ready(function(){

function setToken(){

// Get a Token from the site
$.ajax({
url: "http://localhost/drupal/my_services/user/token",
type: 'POST',
dataType: 'json',
//crossDomain: true,
error: function(XMLHttpRequest, textStatus, errorThrown) {
// Error getting Token
console.log('Get Token Failed');
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (data) {
// Set the Token Value in a textfield
$("#page_login_token").val( data.token );
}
}); // End Ajax
}

function doLogin( tokenid ){
var tokenValue = $(tokenid).val();
$.ajax({
url: "http://localhost/drupal/my_services/user/login",
type: 'POST',
dataType: 'json',
crossDomain: true,
data: {"username":$("#page_login_name").val(),"password":$("#page_login_pass").val()},

beforeSend: function (request) {
request.setRequestHeader("X-CSRF-Token", tokenValue);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function( userdata ){
$("#page_login_session_ID").val( userdata.sessid );
$("#page_login_session_name").val( userdata.session_name );
$("#page_login_username").val("Welkom SUPER" + userdata.user.name +"You are my Hero!");

// Get and Set a new Token after Login!!!
setToken();

}
});
}

function doLogout( tokenid, session_id, session_name ){

$.ajax({
url: "http://localhost/drupal/my_services/user/logout",
type: 'POST',
dataType: 'json',
crossDomain: true,
beforeSend: function (request) {
request.setRequestHeader("X-CSRF-Token", jQuery("#page_login_token").val());
},

error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (data) {
$("#page_login_session_ID").val("");
$("#page_login_session_name").val("");
$("#page_login_username").html("");
$("#page_login_token").val("");
}

});

}

function testConnect( tokenid ){
var tokenValue = $(tokenid).val();
var gorge = tokenValue.substring(14);
$.ajax({
url: "http://localhost/drupal/my_services/system/connect",
type: 'POST',
dataType: 'json',
crossDomain: true,
beforeSend: function (request) {
request.setRequestHeader("X-CSRF-Token", tokenValue);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//alert( 'Error with Connect.json' );
alert( gorge );
console.log( 'Error with Connect.json' );
console.log(JSON.stringify(XMLHttpRequest));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function( data ){
console.log( data );
alert( data );
}
});
}


$(document).on("click", "#page_login_submit", function () {
    //alert("Goodbye!");
    setToken();
    //testConnect( "#page_login_token" );
    doLogin( "#page_login_token" );
});


});// End document ready

4)ポスターとChromeを使用したテスト

Firefoxはテスト分野で少しがっかりした。 ポスター を除く。これにより、Drupal Get/Postを使用してサービスを直接テストできます。テストには非常に便利です。Chrome開発者ツールは非常に便利でした-最初のツールでしたCORS構成の実際の問題を教えてください。

これがお役に立てば幸いです!コメント/アドバイスを追加してください。私はこれを時間内に更新してより良くすることができます。

8
Ken J