技術のネタ

Laravelで目標30分の爆速でWebexOAuth連携をしてみた

菅野
こんにちは、株式会社サンエルのシステム開発部部長の菅野です

最近Webex APIを触る機会が多いので何か記事にしたいと思っていたところ、AdventCalenderのお誘いを受けましたので、AdventCalender向けに書いていきます

お題色々悩んだのですが、Webex第1段はLaravelを使ったWebex連携を「爆速」で実装してみたいと思います。

なぜLaravelかというと、MPAで良いシンプルなシステムの場合、私が最も得意なのがLaravelだからです。SPAの場合Django+Nuxt.jsを使うことが多いです。

ということで今回は、

  1. LaravelでOauth2認証
  2. スペースの一覧を取得

までを目標30分で「爆速」実装していきます!

ただし、Laravelの環境構築やWebexのアカウント作成の時間は除きます。

前提条件・対象

以下を対象としています。

この記事を参考にしてもらいたい対象者

  • Laravelを触ったことある人
  • Webexを触ったことあるけどAPI開発したことない人

つまり「WebexAPIを使った開発ってどうなん?」と疑問を持っている人が、「あ〜、こんな感じか」と対応内容を理解していただければ、と思っています。

環境

今回はLaravel8を使います。私はローカル(Mac)を汚したくないので laradock をベースに、ProductionデプロイまでできるようにカスタマイズしたDocker環境を使ってます

ですが、ローカルで既にComposerが入ってる人は、Laravel Sailを使ってもいいかと思います。

以下、今回実装を行った環境になります。

  • Debian 11.1
  • PHP 8.1
  • Laravel 8
  • Webexアカウント[無償]

Webexアカウントは無償でも構いません。有償版でないとGuestIssuerなど一部使えない機能もありますが、スペース作成やメッセージ投稿など、ベーシックな機能は無償版でもほとんど使えます

それでは行きます!

ログイン(15分)

まず、ログイン部分を作ります。

WebexでAPI連携する場合、Botを使う方法Oauth2認証する方法の2つがあります。

どちらもメリット・デメリットがあります。Botの場合はBot用のTokenが発行されるので、Bearer認証すればいいだけです。

なお、Botでのやり方は世の中にたくさん情報が出ているので省略します。

ではまず Webex for Developers にログインして認証に必要な情報を生成します。

Facebookなど他のOauth2認証をしたことがある人にとっては、お馴染みの設定項目だと思います。

もし分からない人は、シスコ コミュニティのページを参考にしてください。

リダイレクト先

認証後にリダイレクトする先を設定します。

今回はローカルで動かすので、次のようにしました。

http://localhost:8080/login/webex/callback

リダイレクト設定

scopeに注意

ここで一つポイントがあります。それはscopeです。詳細は後述しますがspark:allは使わず、必ずspark:people_readを設定してください

本稿では、このあとルームの一覧表示をするので以下のようにしました。

scopeに注意

これでWebexの環境周りの下準備はOKです。

認証パッケージのインストール

今回、認証部分はlaravel/uiを使うことにします。Laravel8では認証パッケージが刷新されており新しく導入されたJetstreamではCSSがBootstrapからTailwindに変更されています

ですが、個人的にまだ手がついていないので、以前から使い慣れてるlaravel/uiを使います。

認証パッケージ

localhost/loginにアクセスしてログイン画面が出たらOKです。

localhost/loginにアクセス

Socialiteの設定

次にLaravel Socialiteを使います。

Socialiteはソーシャルログインを簡単に提供することができるパッケージで、webex用のSocialiteも対応されていますのでcomposerで入れます。

じつは爆速で実装できるポイントはここにあります。以前はこの部分を自力実装してたので、結構手間でした。

composer

次にconfig/services.phpに設定を追加します。

config/services.php

config/services.php

Laravel知ってる人ならすぐ分かると思いますが、これだけだと意味がありません。.envに実際の値を設定します。

.envに実際の値を設定

.env

最後にProvider周りを設定します。

Provider周りを設定
app/Providers/EventServiceProvider.php

config/app.php
config/app.php

Webexログインの実装

今回は既存のログイン画面にソーシャルログインボタンを追加して、ユーザーが登録されていなかったら登録します。逆に、登録されていたら更新してログインするようにします。

まずはRouteを作ります。

Route

redirectcallbackを追加します。今回はWebexだけですが、Socialiteは他の認証も受けれるようにしておきます。

またhomeは認証済みのみアクセスできるようにauthミドルウェアで括ります

次にマイグレーションを修正します。

マイグレーションを修正

database/migrations/2014_10_12_000000_create_users_table.php

passwordカラムnullableにして、access_tokenカラムを追加してます。今後パスワード認証を追加する場合を考えると、nullableは危険な香りがします。ただ、今回のシステムはwebexアカウントが無いと全く機能しないので、手っ取り早くnullableにします。

access_tokenをsessionに持たせたり、refresh_tokenもきちんと管理するといったことが色々ありますが、今回は爆速ということで一旦無視します。

次にLoginControllerメソッドを追加します。

LoginControllerにメソッドを追加

ポイントはredirectToPrividerscopesです。

scopesはDeveloperサイトで設定したscopesと同じものを設定して下さい

ここで罠が1つあります。それは横着してspark:allを使うと、このコードでは動かないです

理由はSocialiteパッケージ内でspark:people_readがコーディングされているからです。

vendor/socialiteproviders/webex/Provider.php

vendor/socialiteproviders/webex/Provider.php

Developerサイトでspark:allを選択するとspark:people_readが選択できなくなるため、Developerサイトのscope設定とリクエストのscope設定が一致できなくなります

もしどうしてもspark:allを使いたいのであれば、setScopesを使って既存のスコープを上書きする必要があります。

ただしセキュリティ上おすすめしません

Controller

また、今回はControllerがUserモデルを直接呼び出してますが、ある一定規模以上のプロダクトならServiceレイヤーやRepositoryレイヤーを入れた方がいいかと思います。

そして最後に、Webexでのログインボタンを追加します。

Webexでのログインボタン

Webexでログインボタンが表示されました。
cisco wedex_webexでログイン

ボタンを押すとWebexのログイン画面が表示されます。ここで、メールアドレスとパスワードを入力します。
cisco_webex_メールアドレス

設定したscopeに対する確認画面が出るので承認します。
cisco_webex_承認画面

無事ログインできて右上にWebexアカウント名が表示されてたら成功です。
cisco_webex_右上アカウント名

スペース作成(15分)

アクセストークンさえ取得できればあとは楽です。

WebexAPIを利用する専用クラス作成

個別で実装すると無駄なので、先にWebexへのアクセサを作ってしまいます。WebeClientというクラスにしました。接続先がDBなのかWebexなのかの違いでしかないので、このクラスもModels以下に作成します。

WebeClient

app/Models/WebClient.php

特に複雑なことはしてません。

スペース一覧を取得するAPIはオプションで、teamIdtypeの指定などオプション指定があります。ただ今回は特に指定せず全取得します。

コントローラーの作成

既にHomeControllerがあるので、これを加工します。

今後スペースの作成や編集機能を追加するなら、専用のRoomControllerを作った方がいいのですが、今回は「爆速」ですから作りません。

元々あったindexメソッドを修正します。

先程作ったWebeClientのlistRoomsを呼ぶだけです。

WebeClientのlistRoomsを呼ぶ

あとはhome.blade.phpも修正します。

home.blade.phpを修正

ダッシュボード部分にスペースの一覧が出てきたら完成です!

ダッシュボードスペース一覧

おわりに

なんとかギリギリ30分で終わりました。scopeまわりでハマらなければ、もう少し早くできたと思います。

今回は最低限の実装ならどれだけ早く作れるか、というチャレンジでした。

ですが、実際プロダクトレベルにしようとすると、もっと細かい作り込みが必要です。そもそもテストコードすら書いてないですし。

あくまでチャレンジ企画というご認識でお願いします

あと、簡単に実装できたのは、やはりSocialiteにWebexが対応されたことが大きいかと思います。

じつはこの記事を書こうと思ったのは、今までは認証部分を自力で実装してたのですが、お題を考えてるときに、このwebex対応を知ったからです。

https://developer.webex.com/blog/convenient-webex-oauth-for-laravel-projects-with-socialite

対応していただいたCiscoの方に感謝です。

これからWebexAPIを開発する方は、参考にしてみてくださいね。

MieL編集部
「MieL(ミエル)」は地域や企業、人との「つながり」を形として見えるようにしたいという思いから立ち上げました。
運営は三重県松阪市にある「株式会社サンエル(SunL)」が行っています。
MieLでは地元三重の情報をはじめ、サンエルの実績や社員、デジタルテクノロジーについてなど、ビジネスや生活に役立つさまざまなコンテンツを発信していきます。

弊社について詳しく知りたい方はこちら

-技術のネタ
-, , ,

© 2022 MieL