JavaScript를 사용하여 기본 클라이언트에서 Magento API에 액세스하는 방법


9

로컬 JavaScript 기반 응용 프로그램 (Titanium Desktop)에서 Magento API에 액세스하여 가장 좋은 방법이 궁금합니다.

내가 지금까지 알아 낸 것 :

질문 :

  • 인증 메커니즘을 응용 프로그램 키 및 비밀을 사용하여 HMAC 기반 인증과 같은 것으로 교환 할 수 있습니까? 입증 된 솔루션이 있습니까?
  • 그렇지 않은 경우 Magento에서 OAuth 사용자 에이전트 흐름이 가능합니까? 설명서에는 언급되어 있지 않습니다.
  • 사용자로부터 대부분의 인증 프로세스를 숨기기 위해 AJAX (Cross-Origin-Policy는 여기서 문제가되지 않음)로 사용자 자격 증명을 제출할 수 있습니까? 그러면 액세스 토큰을 응답에서 직접 추출 할 수 있습니다.

OK, 나는 REST에 너무 집중했다는 것을 알았습니다 .JavaScript를 사용하는 SOAP는 번거롭지 만 SOAP API는 내 문제를 해결해야합니다. 티타늄 라이브러리 ( github.com/kwhinnery/Suds )가 있습니다. 시험 해보고 결과를 여기에 게시하겠습니다.
Fabian Schmengler

답변:


8

편집 : 더 나은 방법을 찾았습니다. 아래 솔루션 2를 참조하십시오.

의견에서 언급했듯이 SOAP API는 갈 길입니다.

해결책 1 :

Suds 는 약간의 수정 (나를 Titanium.Network.HTTPClient대신 사용)으로 나를 위해 XMLHttpRequest일했지만 호출을위한 SOAP 봉투를 만들고 전체 XML 응답을 반환하는 것 이상은 아닙니다.

요청 체인에 jQuery Deferred 를 사용한 개념 증명 구현 :

Service.MagentoClient = function()
{
    var self = this;
    var suds = new SudsClient({
        endpoint : "http://the-magento-host/api/v2_soap/",
        targetNamespace : "urn:Magento",
    });

    self.login = function() {
        var deferred = new $.Deferred();
        var args = {
            username : 'the-username',
            apiKey: 'the-api-key'
        };
        suds.invoke("login", args, function(xmlDoc) {
            self.sessionId = $(xmlDoc).find("loginReturn").text();
            deferred.resolve({});
            //TODO reject if no sessionid returned
        });
        return deferred;
    };

    self.setStatus = function(orderId, status, comment, notify) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject({ error: 'Login not successful.' });
            return;
        }
        var args = {
            sessionId        : self.sessionId,
            orderIncrementId : orderId,
            status           : status,
            comment          : comment,
            notify           : notify
        }
        suds.invoke("salesOrderAddComment", args, function(xmlDoc) {
            var success = $(xmlDoc).find("salesOrderAddCommentResponse").text();
            if (success) {
                deferred.resolve({});
            } else {
                deferred.reject({ error: 'Update not successful.' });
            }

        });
        return deferred;
    };
};

사용 예 :

        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.setStatus('100000029', 'complete', 'soap test');
        }).then(function() {
            alert('Update successful');
        }, function(reject) {
            alert('Update failed: ' + reject.error);
        });

해결책 2 :

자체 API 어댑터를 작성하는 것이 정말 쉽다는 것이 밝혀졌습니다. 예를 들어이 핵심 핵(데드 링크)에 기반한 JSON-RPC 어댑터에 대한 깨끗한 모듈을 작성할 수있었습니다 Zend_Json_Server. SOAP 및 XML-RPC API와 동일한 인증 및 ACL을 사용합니다.

진입 점을 사용하려면 /api/jsonrpc새 컨트롤러를 api경로에 추가해야 합니다.

<config>
    <frontend>
        <routers>
            <api>
                <args>
                    <modules>
                        <my_jsonrpc before="Mage_Api">My_JsonRpc_Api</my_jsonrpc>
                    </modules>
                </args>
            </api>
        </routers>
    </frontend>
</config>

2015 년 2 월 업데이트 : 위의 링크가 현재 종료되었으므로 JSON-RPC 어댑터를 완전한 확장으로 소스로 열었습니다 : https://github.com/sgh-it/jsonrpc

내 JS 클라이언트는 이제 다음과 같습니다 (JQuery.Deferred와 함께 추가되지만 API에 대한 추가 타사 라이브러리는 없습니다).

/**
 * Client for the Magento API
 */
Service.MagentoClient = function()
{
    var self = this;

    /**
     * @param string   method    the remote procedure to call
     * @param object   params    parameters for the RPC
     * @param callback onSuccess callback for successful request. Expects one parameter (decoded response object)
     * @param callback onError   callback for failed request. Expects one parameter (error message)
     * 
     * @return void
     */
    self.jsonRpc = function(method, params, onSuccess, onError) {
        var request = {
            method : method,
            params : params,
            jsonrpc : "2.0",
            id : 1
        };

        var options = {
            entryPoint : config.magentoClient.entryPoint,
            method: 'post',
            timeout: config.magentoClient.timeout
        };

        var httpClient = Titanium.Network.createHTTPClient();
        httpClient.onload = function(e) {
            try {
                var response = JSON.parse(this.responseText);
            } catch (jsonError) {
                return onError(jsonError);
            }
            if (response.error) {
                if (response.error.code == 5) { // session expired
                    self.sessionId = null;
                }
                return onError(response.error.message);
            }
            onSuccess(response);
        };
        httpClient.onerror = function(e) {
            onError(e.error + '; Response:' + this.responseText);
        };
        httpClient.setTimeout(options.timeout);

        if (httpClient.open(options.method, options.entryPoint)) {
            httpClient.setRequestHeader("Content-type", "application/json");
            httpClient.send(JSON.stringify(request));
        } else {
            onError('cannot open connection');
        }

    }
    /**
     * Retrieve session id for API
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.login = function() {
        var deferred = new $.Deferred();
        if (self.sessionId) {
            deferred.resolve();
            return deferred;
        }
        var loginParams = config.magentoClient.login;
        try {
            self.jsonRpc('login', loginParams, function(response) {
                if (response && response.result) {
                    self.sessionId = response.result;
                    deferred.resolve();
                } else {
                    deferred.reject('Login failed.');
                }
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }
        return deferred;
    };
    /**
     * Updates order states in Magento
     *
     * @param string method   name of the remote method
     * @param object args     arguments for the remote method
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.call = function(method, args) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject('No session.');
            return;
        }
        var callParams = {
            sessionId : self.sessionId,
            apiPath   : method,
            args      : args
        };
        try {
            self.jsonRpc('call', callParams, function(response) {
                deferred.resolve(response.result);
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }

        return deferred;
    };
};

로그인 후 모든 메소드는를 통해 라우팅됩니다 call. method파라미터 등 무언가 sales_order.list1, args파라미터에있어서의 인수 배열 또는 개체.

사용 예 :

        var filters = [];
        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.call('sales_order.list', [filters]).then(
                function(orders) {
                    // do something with the response
                }, function(error) {
                    alert('Magento API error: ' + error);
                }
            );
        });

스크립트에서 엔드 포인트를 구성하는 방법은 무엇입니까?
Akrramo

프론트 엔드 라우터 정의를 다음과 같이 변경 config.xml해야 api합니다 (라우트 를 사용하지 않으려면 대신 커스텀 라우트를 사용할 수 있습니다. 다른 Magento 모듈에서와 같이 정의하십시오)
Fabian Schmengler

이 코드를 magento에 넣을 수있는 곳
er.irfankhan11

설치 지침이 있습니다 github.com/sgh-it/jsonrpc
파비안 Schmengler

그리고 JavaScript 코드는 분명히 Magento가 아니라 외부 클라이언트에 속합니다
Fabian Schmengler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.