EC-CUBE4のGraphQL APIをいじってみた
今回はゴリゴリの技術系の記事です。
合同オンライン勉強会でネタにしたEC-CUBE4のGraphQL APIがうまく動かなかったので、再度自分の環境を構築して色々やってみました。
なお、この作業をやるまで筆者はGraphQLの知識はありましたがOAuth2の知識はあまりありませんでした。OAuth2の良い勉強になりました...
GraphQL APIが動く環境をまず準備
勉強会の時に用意してもらった環境でうまく認証ができなかったので、その辺りのデバッグをするためにもとりあえず自前の環境にAPIが動いてるEC-CUBE4を準備します。
インストール
とりあえずgithubからAPIのブランチをチェックアウト。
管理画面にログインしようとするとエラー
Key path "file:///var/www/html/var/oauth/public.key" does not exist or is not readable
どうもvar/oauth/public.key
に鍵が必要らしい。
どこでどう鍵の生成と設定するのかわからないので公式のドキュメントをチェック。
https://doc4.ec-cube.net/api_quickstart_guidedoc4.ec-cube.net
mkdir var/oauth openssl genrsa -out private.key 2048 openssl rsa -in private.key -pubout -out public.key mv private.key var/oauth mv public.key var/oauth
とのことなので指定された手順で鍵を生成。しかしドキュメントルート配下に秘密鍵を置いておくのは怖いな...
無事、エラーが解消されインストール、管理画面にログインできるようになりました。
クライアントの登録
公式のドキュメントによると、APIを利用するクライアントを予め登録しておく必要があるとのこと。これは初心者にはキツイですね...(上記の鍵の生成とかもですが)
とりあえずまだBetaなので、実際にリリースされるときはもっと使いやすい形のプラグインとしてリリースされると言ってたので、管理画面からのオーナーズストアへの接続時の様に鍵の生成とかも管理画面に機能が実装されるでしょう。
とりあえず、自前のconcrete5からAPIを叩いて商品情報を取得、表示させるというのをまずやりたいので、ドキュメントに記載されている方法でクライアントを登録。
bin/console trikoder:oauth2:create-client client_identifier client_secret --redirect-uri=https://www.xross-cube.com/graphql-test --grant-type=authorization_code --grant-type=client_credentials --grant-type=implicit --grant-type=password --grant-type=refresh_token --scope=read --scope=write
ハイ!エラー!
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ecdev.oauth2_client' doesn't exist
どうやら以前使ってた環境のDBをそのまま利用してたのがダメだった様で、必要なテーブルが足りて無いぞと怒られてしまいました。
なので、schemaをアップデートします。
./bin/console eccube:schema:update --force ./bin/console cache:clear --no-warmup
無事、クライアントを登録できました。
[OK] New oAuth2 client created successfully. ------------------- --------------- Identifier Secret ------------------- --------------- client_identifier client_secret ------------------- ---------------
Authorization code grant での認証
次に、登録したクラインとからAPI叩ける様に認証を行います。
MacでのAPIのテストツールとして便利なInsomniaを使ってテストします。
ここまでの設定で指定した各パラメータをInsomniaの認証-OAuth2のところに入れていきます。
トークンを取得するために、Fetch Tokens
をクリック!
ハイ!エラー出ましたー!
No route found for "GET /admin/authorize"
今度は/admin/authorizeなんてURL無いよって怒られてしまいました。そうでした、そう言えば管理画面のURIをadminじゃないものでインストールしていました。 なので、パラメータを変更して再度実行。 EC-CUBEの管理画面のログイン画面が出てきました。
ここで管理画面ユーザのログイン情報を入力してログイン。
確認画面が表示されるので、許可をクリック。
ハイ!エラー出ましたー!
Environment variable not found: "OAUTH2_ENCRYPTION_KEY".
前にインストールしてたEC-CUBEの環境を流用しているせいで、必要なパラメータの設定が.env
になかったのが原因の様です。*2
なので、.env
にOAUTH2_ENCRYPTION_KEY
を追加。値は任意のランダムな文字列を指定して再度チャレンジ。
ハイ! エラー出ましたー!
OAuth 2.0 Error invalid_scope The requested scope is invalid, unknown, or malformed null
どうもInsomniaでscopeを指定する際に、read, write
の様に「,」で区切っちゃいけなかったみたいです。スペース区切りで指定しないといけない様です。
カンマ決して、再度Fetch Tokens!
無事、認証が通りtokenが取れました! いやー、ここまで長かった〜
GraphQLのクエリを投げてみる
無事、認証が通り、クエリを投げれる様になったので、Insomniaを使ってクエリを投げてみます。
リクエストはクエリをjson形式で書いて、POSTで投げます。
{ products{ id, name, description_list, ProductImage{ file_name }, ProductClasses{ stock, stock_unlimited, price02 } } }
無事、レスポンスが返ってきました。
いやー、長かった!
実際に他のアプリからAPIを叩いてみる。
さて、無事APIが正常に稼働している事は確認できましたが、このままでは使い物になりません。
他のWebサイトやモバイルアプリなどからAPIを叩いて情報を取得、処理して初めてAPIとして用途が生まれてきます。
EC-CUBEの公式のドキュメントでもその辺りまでは詳しく記載されていなかったので、ここからは手探りです。
concrete5のブロックとして商品一覧を実装してみる。
まず、汎用型CMSであるconcrete5に組み込み込んでみます。concrete5のブロックからEC-CUBEのAPIを叩いて商品一覧を取得する感じです。
ここでちょっと疑問に思ったのが、あの管理画面のログイン画面とかAPI認証の画面がconcrete5で表示される様になるのかな?ってとこですが、とりあえずやってみます。
concrete5でOAuth2認証
concrete5では、標準でzend frameworkのhttpクライアントが使えます。なので、認証トークンさえ取れてしまえば、GraphQL叩く事自体は簡単です。
とりあえず使えそうなOAuth2クライアントライブラリを探します。
久しぶりにZend Frameworkのドキュメントサイト見て知ったんですが、今ってもうZend Frameworkじゃないんですね。Laminas Projectとかいうのになっててちょっと驚きました。 githubのリポジトリも https://github.com/laminas-api-tools/api-tools-oauth2 に変わってて新しくなってました。
で、これを読んでて思い出したのですが、concrete5はOAuthに対応してて、twitterやfacebookのアカウントでログインできる機能があります。その辺りの認証の処理を流用できればうまくできるんじゃないかなぁと思って、concrete5のその辺のコードを読んで解析しました。
いやー、そのものズバリなのが既にありました。 https://documentation.concrete5.org/api/8.0.1/Concrete/Core/Authentication/Type/OAuth/OAuth2/GenericOauth2TypeController.htmldocumentation.concrete5.org これを流用してconcrete5からEC-CUBEへの認証を実装します。
余談ですが、concrete5自体にもAPI機能は実装されており、EC-CUBEからconcrete5のAPIを叩くとかも可能です。その際に利用できそうなのが、concrete5が出しているOAuth2 Clientです。 github.com Thanks Andrew!! Your work is great!
と、この辺りで今日は時間がきてしまったので、続きはまた後日書きます。
お楽しみに!