共通管理メニュー内の[外部連携]で、
OAuthクライアントの作成
ができるようになりました。
今回は、Ruby on Rails(以下、Rails)で作成した顧客お問い合わせサイトから入力したデータを、OAuth 2.0の承認を経て、kintone APIでデータを追加するサンプルを紹介します。
kintoneアプリの作成
OAuthクライアントの設定
Railsクライアントアプリケーションの開発
Herokuへのデプロイ
動作確認
1. kintoneアプリの作成
固定リンクがコピーされました
kintoneアプリストアより、「お客様の声管理」で検索し、表示されたアプリを追加します。
このとき作成したkintoneアプリのアプリIDをメモしてください。Railsアプリケーションの作成時に利用します。
アプリIDは、kintoneアプリを開いたときのURLで確認できます。
https://{subdomain}.cybozu.com/k/{アプリID}
次のテーブルを参考にフィールドコードを設定します。
フィールドの種類
フィールド名
フィールドコード
ドロップダウン
収集媒体
received_via
ドロップダウン
カテゴリ
category
ドロップダウン
テナント名
tenant_name
文字列(複数行)
ご意見内容
opinion
kintoneアプリの設定は以上です。
2. OAuth Clientの設定
固定リンクがコピーされました
kintoneアプリのcybozu.com共通管理ページより、外部連携の設定画面にて、OAuthクライアントの追加をクリックします。
操作方法の詳細は、
OAuthクライアントを追加する
を参照してください。
「クライアント名」と「リダイレクトエンドポイント」を入力します。
「リダイレクトエンドポイント」は、サイトをHerokuへデプロイした際に決定します。
今の段階では、次の値を仮設定しておき、のちほど変更します。
仮のリダイレクトエンドポイント: https://localhost:3000/authorize(必ずhttpsを指定してください)
「保存」すると、以下の情報が自動生成されます。
「クライアントID」と「クライアントシークレット」をメモしてください。Railsアプリケーションの作成時に利用します。
クライアントID
クライアントシークレット
認可エンドポイント
トークンエンドポイント
連携利用ユーザーの設定をクリックします。
API利用を許可するユーザーを選択し、設定を保存します。
以上でOAuthクライアントの設定は終了です。
3. Railsクライアントアプリケーションの開発
固定リンクがコピーされました
Ruby on Railsでクライアントアプリケーションを開発していきます。
ステップ 1
ターミナルを開き、次のコマンドを実行して、Railsのアプリケーションを作成します。
1
rails new customer-feedback
これにより、customer-feedbackというプロジェクト名でRailsのアプリケーションのひな型が生成されます。
以下のコマンドでローカルサーバーを起動し、動作するか確認します。
サーバーが起動したら、ブラウザーにてhttp://localhost:3000
を開き、以下のように表示されたら成功です。
1
2
cd customer-feedback
rails server
注意事項
(Windows環境)
SQLite3でdlopenの関数が存在しないというエラーになった場合、以下コマンドを実施してください。
1
ridk exec pacman -S mingw-w64 -x86_64-dlfcn
ステップ 2
今回は、OAuth2.0を使うので、以下のようにGemfileに2つのgemを追加してください。
oauth2は、OAuthリクエストを実行するために使用し、activerecord-session_storeはセッションの情報をデータベースへ記録するために使用します。
1
2
gem 'oauth2'
gem 'activerecord-session_store'
ファイルを保存後、以下のコマンドを実行します。
次に以下のコマンドを実行し、セッションの保存用のデータベースを作成します。
1
2
rails generate active_record:session_migration
rails db:migrate
ステップ 3
続いて、以下のコマンドで、「home」、「auth」と「feedbacks」というコントローラーを作成します。
1
2
3
rails generate controller home
rails generate controller auth
rails generate controller feedbacks
ステップ4
次に「app」-「helpers」フォルダー内の「auth_helper.rb」を開き、以下を参考にコーディングします。
次の値は、利用環境に合わせて修正してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# Rails x kintone OAuth client sample program
# Copyright (c) 201x Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/
module AuthHelper
# kintone側のOAuth設定のクライアントID
CLIENT_ID = '{クライアントID}'
# kintone側のOAuth設定のクライアントシークレット
CLIENT_SECRET = '{クライアントシークレット}'
# kintoneのURL
SITE = 'https://{サブドメイン名}.cybozu.com'
# 認可エンドポイント
AUTHORIZE_URL = '/oauth2/authorization'
# トークンエンドポイント
TOKEN_URL = '/oauth2/token'
# APIアクセスのスコープ設定read/write権限
SCOPES = ['k:app_record:read' ,'k:app_record:write' ]
# CSRF対策のランダムな値
STATE = SecureRandom.alphanumeric
# ログインURLの生成
def get_login_url
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
login_url = client.auth_code.authorize_url(:redirect_uri => authorize_url, # Railsの認可ページへのルートパス
:scope => SCOPES.join(' ' ),
:state => STATE)
end
# アクセストークン取得のための認可コードを送信
def get_token_from_code (auth_code)
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
token = client.auth_code.get_token(auth_code,
:redirect_uri => authorize_url,
:scope => SCOPES.join(' ' ))
end
# アクセストークンの取得
def get_access_token
# セッションから現在のアクセストークンハッシュを取得
token_hash = session[:kintone_token ]
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
token = OAuth2::AccessToken.from_hash(client, token_hash)
# アクセストークンが期限切れの場合、リフレッシュトークンからアクセストークンを取得
if token.expired?
new_token = token.refresh!
# 新アクセストークンをセッションへ保存
session[:kintone_token ] = new_token.to_hash
access_token = new_token
else
access_token = token
end
end
end
ステップ5
今度は、「app」>「controllers」フォルダー内の「home_controller.rb」を以下のように編集します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Rails x kintone OAuth client sample program
# home_controller.rb
# Copyright (c) 201x Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/
class HomeController < ApplicationController
include AuthHelper
def index
# 承認リンクの表示
@login_url = get_login_url
end
end
また、同フォルダー内の「auth_controller.rb」を以下を参考にコードを追加します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Rails x kintone OAuth client sample program
# auth_controller.rb
# Copyright (c) 201x Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/
class AuthController < ApplicationController
include AuthHelper
# 認可コードからアクセストークンを取得
def gettoken
token = get_token_from_code params[:code ]
session[:kintone_token ] = token.to_hash
redirect_to feedbacks_url
end
end
最後に「feedbacks_controller.rb」を以下を参考に編集します。
次の値は、利用環境に合わせて修正してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Rails x kintone OAuth client sample program
# feedback_controller.rb
# Copyright (c) 201x Cybozu
#
# Licensed under the MIT License
# https://opensource.org/license/mit/
class FeedbacksController < ApplicationController
include AuthHelper
# kintoenのアプリケーションID
APP_ID = '{アプリケーションID}'
DOMAIN = 'https://{サブドメイン名}.cybozu.com'
def new
# 初期ページロード状態では何もしない
end
def create
@feedback = Feedback.new(feedback_params)
if @feedback.save
token = get_access_token
if token
# アクセストークンがすでに取得されている場合、データをkintoneへポスト
# ハッシュ形式でレコードを設定
#
record = {
"app" => APP_ID,
"record" => {
"received_via" => {
"value" => feedback_params[:received_via ]
},
"category" => {
"value" => feedback_params[:category ]
},
"tenant_name" => {
"value" => feedback_params[:tenant_name ]
},
"opinion" => {
"value" => feedback_params[:opinion ]
}
}
}
response = token.post(" #{ DOMAIN} /k/v1/record.json" , {:body => record.to_json, :headers => {'Authorization' => "Bearer #{ token.token} " , 'Content-Type' => 'application/json' }})
redirect_to feedbacks_url
else
# アクセストークンが存在しない場合、ホームページへ戻り、承認のやり直し
#
redirect_to root_url
end
else
render 'new'
end
end
private
def feedback_params
# フォームからデータを取得
params.require(:feedback ).permit(:received_via , :category , :tenant_name , :opinion )
end
end
ステップ6
「app」>「views」>「home」フォルダー内に「index.html.erb」ファイルを作成し、以下を参考にしてホームページを作成します。
「kinrtoneへ接続」するためのリンクを設置しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--
* Rails x kintone OAuth client sample program
* home_controller.rb
* Copyright (c) 201x Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
-->
<h1>kintone OAuth 2.0クライアントサンプル</h1>
<p>
<a href="<%= @login_url %>" role="button" id="connect-button">kintoneに接続</a>
</p>
次のようなページが生成されます。
次に、「app」>「views」>「feedbacks」フォルダー内に「new.html.erb」ファイルを作成し、以下を参考にして、お客様の声フォームを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!--
* Rails x kintone OAuth client sample program
* home_controller.rb
* Copyright (c) 201x Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
-->
<h1>お客様の声</h1>
<%= form_for :feedback, url: feedbacks_path do |form| %>
<p>
<%= form.hidden_field :received_via, value: "WEBサイトから" %>
<%= form.label :category, "カテゴリ:" %><br>
<%= form.select :category,
[['---','---'],
['お褒め','お褒め'],
['お叱り','お叱り'],
['ご要望','ご要望'],
['その他','その他'],]
%>
</p>
<p>
<%= form.label :tenant_name, "テナント名:" %><br>
<%= form.select :tenant_name,
[['---',''],
['坊主食品','坊主食品'],
['サイボシューズ','サイボシューズ'],
['Cミュージックストア','Cミュージックストア'],
['施設','施設'],]
%>
</p>
<p>
<%= form.label :opinion, "ご意見内容:" %><br>
<%= form.text_area :opinion, size: "50x6" %>
</p>
<p>
<%= form.submit "送信" %>
</p>
<% end %>
次のようなページが生成されます。
ステップ 7
次に「config」フォルダー内の「routes.rb」ファイルを以下のように編集します。
1
2
3
4
5
6
7
Rails.application.routes.draw do
root 'home#index'
get '/authorize' => 'auth#gettoken'
get '/feedbacks' , to : 'feedbacks#new'
post '/feedbacks' , to : 'feedbacks#create'
resources :feedbacks
end
HTTP動詞
パス
フィールドコード
目的
GET
/authorize
auth#gettoken
OAuthでkintoneからのコールバック先
GET
/feedbacks
feedbacks#new
お客様の声を1つ作成するためのHTMLフォームを返す
POST
/feedbacks
feedbacks#create
お客様の声を1つ作成する
ステップ 8
次にさきほど指定したresource名のモデルを生成します。
次のコマンドを実行し、「feedback」モデルを生成します。ここでは「feedbacks」ではなく、単数形の「feedback」を指定します。
1
rails generate model feedback received_via:string category:string tenant_name:string opinion:text
これにより以下のモデルが生成されます。
フィールド名
フィールドタイプ
received_via
string
category
string
tenant_name
string
opinion
text
以下のコマンドでマイグレーションを実行して、データベースにテーブルを作成します。
これでfeedbacksテーブルがデータベース上に作成されます。
テスト環境での動作確認
以下のコマンドでローカルのRailsサーバーを起動し、エラーがないか確認します。
以下の画像のようにホームページが表示されれば、成功です。
ただし、「kintoneに接続」リンクをクリックしてもkintone側のOAuthクライアントのコールバックURLの設定が異なるためエラーになります。
これは、Herokuへのデプロイが終了後、修正します。
以上で、Railsクライアントの開発は完了です。
4. Herokuへのデプロイ
固定リンクがコピーされました
今回は、テスト用のサーバーにHerokuを使用します。
Herokuでは、データベースとして利用しているSQLite3はサポートされていません。
そのため、開発環境(ローカル)ではSQLite3を利用し、本番環境(Heroku)ではPostgreSQLを利用するようにします。
GemfileのSQLite3に関する記述部分を以下のように書き換えます。
1
2
3
4
5
6
7
group :production do
gem 'pg'
end
group :development, :test do
gem 'sqlite3' , '~> 1.4'
end
以下のコマンドで、変更をローカルの開発環境に一度反映させます。
1
bundle install --without production
以下のコマンドで、今までのプロジェクトファイルの変更をGitレポジトリに反映させます。
1
2
git add -A
git commit -am "Update Gemfile for Heroku "
以下のコマンドで、Herokuアカウントにログインして、SSHキーを追加します。
1
2
heroku login
heroku keys:add
以下のコマンドでHerokuのアプリケーションを作成します。
Heroku内に空のアプリケーションが作成されるので、次のコマンドで、作成したOAuthクライアントのアプリケーションをHerokuにデプロイします。
次のコマンドでHeroku上にデータベースを作成します。
1
heroku run rake db:migrate
以上でHerokuのデプロイは完了です。
デプロイが完了したら、以下のコマンドで、アプリケーションを開きます。
以下の画像のように表示されれば成功です。
表示されたHerokuのアプリケーションのURLをメモしてください。後述のOAuthクライアントの設定で利用します。
次に、kintoneのOAuthクライアントの設定画面を開き、リダイレクトポイントのURLをHerokuのアプリケーションのURLに変更し、保存します。
「kintone OAuth 2.0クライアントサンプル」フォームに戻り、「kintoneに接続」リンクをクリックします。
kintoneにログインしていない場合は、ログイン画面が表示されます。
「Ruby OAuthクライアントから次の操作が実行されます」というメッセージが表示されるので、「許可」します。
「お客様の声」フォームが表示されるので、各項目を任意に入力し「送信」ボタンをクリックします。
エラー画面が表示されず、フォームの各項目が未入力の状態にリセットされれば、成功です。
kintoneアプリにレコードが追加されているか確認します。
OAuth2.0を使って、Ruby on Railsの外部アプリからkintone APIを使ってレコードの追加に成功したことを確認できました。
auth_helper.rb
固定リンクがコピーされました
auth_helper.rbは、認証に関する処理をまとめたhelperファイルです。
2. OAuth Clientの設定
で作成したOAuthクライアントアプリの値を元に各変数を設定します。
なお、設定したスコープの詳細は、
kintoneのOAuthスコープ
を参考にしてください。今回は、「read」、「write」権限を設定しています。
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# kintone側のOAuth設定のクライアントID
CLIENT_ID = '{クライアントID}'
# kintone側のOAuth設定のクライアントシークレット
CLIENT_SECRET = '{クライアントシークレット}'
# kintoneのURL
SITE = 'https://{サブドメイン名}.cybozu.com'
# 認可エンドポイント
AUTHORIZE_URL = '/oauth2/authorization'
# トークンエンドポイント
TOKEN_URL = '/oauth2/token'
# APIアクセスのスコープ設定read/write権限
SCOPES = ['k:app_record:read' ,'k:app_record:write' ]
# CSRF対策のランダムな値
STATE = SecureRandom.alphanumeric
この関数では、ホームページの「承認」リンクに設定するURLを生成しています。
なお、authorize_urlは、routes.rbで設定するauthorizeページへのルートパスです。このリンクをクリックすると、kintone側から、認可コードが送信されます。
oauth2のプラグインのコマンドの詳細は、
A Ruby wrapper for the OAuth 2.0 protocol
を参照してください。
25
26
27
28
29
30
31
32
33
34
35
36
# ログインURLの生成
def get_login_url
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
login_url = client.auth_code.authorize_url(:redirect_uri => authorize_url, # Railsの認可ページへのルートパス
:scope => SCOPES.join(' ' ),
:state => STATE)
end
こちらの関数では、上記で取得した認可コードからアクセストークンを取得しています。
38
39
40
41
42
43
44
45
46
47
48
49
# アクセストークン取得のための認可コードを送信
def get_token_from_code (auth_code)
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
token = client.auth_code.get_token(auth_code,
:redirect_uri => authorize_url,
:scope => SCOPES.join(' ' ))
end
この関数では、セッションに保存してあるアクセストークンのハッシュから、アクセストークンを取得します。
すでにアクセストークンが期限切れの場合にリフレッシュトークンより、新アクセストークンを取得します。
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# アクセストークンの取得
def get_access_token
# セッションから現在のアクセストークンハッシュを取得
token_hash = session[:kintone_token ]
client = OAuth2::Client.new(CLIENT_ID,
CLIENT_SECRET,
:site => SITE,
:authorize_url => AUTHORIZE_URL,
:token_url => TOKEN_URL)
token = OAuth2::AccessToken.from_hash(client, token_hash)
# アクセストークンが期限切れの場合、リフレッシュトークンからアクセストークンを取得
if token.expired?
new_token = token.refresh!
# 新アクセストークンをセッションへ保存
session[:kintone_token ] = new_token.to_hash
access_token = new_token
else
access_token = token
end
end
home_controller.rb
固定リンクがコピーされました
承認リンクへのURLを取得して、ホームページにリンクを表示します。
11
12
13
14
15
def index
# 承認リンクの表示
@login_url = get_login_url
end
end
auth_controller.rb
固定リンクがコピーされました
kintone側でコールバックされた後、返された認可コードから、アクセストークンを取得します。
12
13
14
15
16
def gettoken
token = get_token_from_code params[:code ]
session[:kintone_token ] = token.to_hash
redirect_to feedbacks_url
end
feedback_controller.rb
固定リンクがコピーされました
いったん、お客様フォームのデータをサイト内のデータベースに保存し、アクセストークンがすでに存在するかチェックします。
21
22
23
24
25
if @feedback.save
token = get_access_token
if token
# アクセストークンがすでに取得されている場合、データをkintoneへポスト
kintoneに送信するデータをハッシュ形式で設定します。
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# ハッシュ形式でレコードを設定
#
record = {
"app" => APP_ID,
"record" => {
"received_via" => {
"value" => feedback_params[:received_via ]
},
"category" => {
"value" => feedback_params[:category ]
},
"tenant_name" => {
"value" => feedback_params[:tenant_name ]
},
"opinion" => {
"value" => feedback_params[:opinion ]
}
}
}
取得したアクセストークンで、kintoneへデータをポストします。
47
response = token.post(" #{ DOMAIN} /k/v1/record.json" , {:body => record.to_json, :headers => {'Authorization' => "Bearer #{ token.token} " , 'Content-Type' => 'application/json' }})
アクセストークンが存在しない場合、ホームページの承認リンクへリダイレクトします。
51
52
53
# アクセストークンが存在しない場合、ホームページへ戻り、承認のやり直し
#
redirect_to root_url
お客様の声フォームより、各データを取得します。
60
61
62
63
64
private
def feedback_params
# フォームからデータを取得
params.require(:feedback ).permit(:received_via , :category , :tenant_name , :opinion )
end
routes.rbは、Railsアプリケーションのルーティング設定するファイルです。
リソース名に「feedbacks」を指定します。
また、ホームページには、承認リンクを表示するページを設定します。
今回はRuby on Railsによって、OAuth2.0を使った外部連携をしました。
これを応用すれば、他の言語で開発したWebアプリケーションからOAuth2.0を使ったkintone APIの利用も可能です。
OAuth2.0による外部連携をすることで、ユーザ毎にkintone APIへのアクセス権限をコントロールできます。