loopbackで作成したプロジェクトでSlackログインできる様にする

f:id:hideack:20171126122221p:plain先日から試行錯誤していた内容のまとめ。

いまloopback.ioを利用してAPIを作ることに取り組んでいるのだけれども、frameworkが提供するユーザ認証の仕組み(メールアドレス及びパスワード)だけではなく、Node.js向けの認証ミドルウェアであるPassportを利用して他の認証機構を利用しようという取り組み。

loopback + passport でfacebooktwitterのアカウントを利用したソーシャルログインの話題は散見するのだけれども、passport-slackを使ってloopbackフレームワークで作成するプロジェクトでのユーザ認証をする話をあまりみかけず、あれこれ試行錯誤した...。

基本的にloopbackプロジェクトが用意しているpassportを利用したユーザ認証のサンプルが以下にあるのでこれに倣えばよい。

github.com

ただサンプルと作り始めているプロジェクトの差分がどこなのだ問題がはっきりせず苦労したので、主に差分を中心にまとめます。

大前提

https://api.slack.com/apps を開いてユーザ認証に使いたいアプリケーションの情報を追加する。

Redirect URIにローカルで開発する用に http://localhost:5000/auth/slack/callback といった形で登録しておく。併せてApp Credentials から Client ID と Client Secret を控えておいて、.env に以下の様な形で書いておく。

SLACK_CLIENT_ID=12345.6789
SLACK_CLIENT_SECRET=xxxyyyzzz

passportでユーザ認証させるために必要なnpmパッケージを導入

先のサンプルで加えられているnpmパッケージと、Slackログインさせるためのpassport-slackをインストールする。

$ npm install --save connect-ensure-login
$ npm install --save cookie-parser
$ npm install --save express-flash
$ npm install --save express-session
$ npm install --save loopback-component-passport
$ npm install --save loopback-passport
$ npm install --save passport-slack

passportが各種情報を収めるモデルを用意する

https://github.com/strongloop/loopback-example-passport で追加されてるモデルを追記する。

上のモデルをloopbackがデフォルトで作成するUserモデルに紐付ける

common/models/user.json

{
  "name": "user",
  "plural": "users",
  "base": "User",
  "properties": {},
  "validations": [],
  "relations": {
    "accessTokens": {
      "type": "hasMany",
      "model": "accessToken",
      "foreignKey": "userId"
    },
    "identities": {
      "type": "hasMany",
      "model": "userIdentity",
      "foreignKey": "userId"
    },
    "credentials": {
      "type": "hasMany",
      "model": "userCredential",
      "foreignKey": "userId"
    }
  },
  "acls": [],
  "methods": {}
}

上の一通りのモデルの設定を server/model-config.json に追記する。

 {
   "_meta": {
     "sources": [
       "loopback/common/models",
       "loopback/server/models",
       "../common/models",
       "./models",
+      "./node_modules/loopback-component-passport/lib/models"
     ],
     "mixins": [
       "loopback/common/mixins",
       "loopback/server/mixins",
       "../common/mixins",
       "./mixins"
     ]
   },
   "User": {
     "dataSource": "db",
     "public": false
   },
   "AccessToken": {
     "dataSource": "db",
     "public": false
   },
+  "userCredential": {
+    "dataSource": "db",
+    "public": false
+  },
+  "userIdentity": {
+    "dataSource": "db",
+    "public": false
+  },

server/server.js に追記

loopbackのcliツールであるlbコマンドで作ったプロジェクトでデフォルトで作成されたファイルをサンプルのものに置き換える。

ここで今回自分は設定ファイルをJSONではなくてJSで取る様にしたので以下の様に修正した。(.envからOAuthのパラメータ取ってもらいたかったので)

var config = {};
try {
  config = require('../providers.js');  // JSにしただけ
} catch (err) {
  console.trace(err);
  process.exit(1); // fatal
}

Slackログイン用の各種情報を書いたproviders.js を置く

.env に記載したClient IDとClient Secretが差し込まれる様にしている。

module.exports = {
  "slack-login": {
    "provider": "slack",
    "module": "passport-slack",
    "clientID": process.env.SLACK_CLIENT_ID,
    "clientSecret": process.env.SLACK_CLIENT_SECRET,
    "authPath": "/auth/slack",
    "callbackURL": "/auth/slack/callback",
    "callbackPath": "/auth/slack/callback",
    "successRedirect": "/",
    "failureRedirect": "/signin",
    "scope": ["identity.basic", "identity.email", "identity.avatar", "identity.team"],
    "failureFlash": true
  }
};

ここまでできたらloopbackのプロジェクト立ち上げて /auth/slack にアクセスすると一度Slackへ遷移したのち認証に成功するとコールバックしてくるのが確認できる。

ブレイブ 勇敢なる者「硬骨エンジニア」を観る - 徒然日記

録画していたものを観る。

「技術は自由にさせるマネージメントをしないと絶対発達しない」

というキーワードが印象に残ったのと、その時点で世間で最善手とされていない方法でも自身が選んだ道を信じてやりぬくことが大事なんだな。と。

www.nhk.or.jp

突発的呑み会, 1on1 - 徒然日記

1on1

今日は自分の1on1ということで自分の上長にあれこれおしゃべりする日。

自分の場合、2週間〜3週間に一度のペースで設けていただいているのだけれども自分としては絶妙な間隔な気がしていてこれより短いと頻繁すぎるし、長すぎると意外とその間に携わっている仕事の経過が大分経っていたりするので。 もちろん雑談成分もあるのだけれども、雑談すらする余裕がないかどうかも気づける場でもあるのでとてもありがたい。

そういえばメモどういった内容取っているの?という話になったので自分が取っているメモの話をさせていただいたりしていた。興味ある方は以下を是非参照くださいませ。

hideack.hatenablog.com

呑み会

最寄り駅が一緒という理由で四半期毎に一度くらい行っている若手エンジニア氏と串かつとお酒の摂取。 気づけば年齢一回りくらい離れているわけで、なんか自分が忘れてた技術を含むいろいろな事柄へのモチベーションだったりを毎回思い出させてくれる貴重な機会になっている。

徒然日記

通勤中に日曜日深夜に放送されるジブリ汗まみれを聞いて出勤する。徳間書店初代社長の徳間康快さんについての話でこの豪快さはどこから出てくるものだろうとぼんやり思いながら渋谷に到着。Wikipedia眺めたらそれとなく豪快さを感じたりもした。

徳間康快 - Wikipedia

仕事で使っているMacが先日ぶっ飛んだので徐々に環境を復旧させながら仕事を進める。気づくとあれやこれや足りないことに気づいたり、復旧できないものが2,3存在することに凹みながら前へ進む。

団子坂奇談, 読んだ本 - 徒然日記

落語

たまには落語でも聞いてみようかと渋谷らくごポッドキャストを開いて入船亭扇里の「団子坂奇談」という落語を聞く。 何気に聞いたら怪談話で一層寒くなった。夏に聞くべきだった。 こういった怪談話でも最後にオチが設けられているんだというのを知って勉強になった。

師匠の入船亭扇橋の落語がYouTubeにあったので貼っておく

www.youtube.com

社長の「まわり」の仕事術を読み始める。 社長のまわりに限らず何かしら人に添って仕事をすることはあるわけで、そうしたときのコツやtipsが詰まっている本という視点で読んでも面白いんじゃないかなと思う。

社長の「まわり」の仕事術(しごとのわ)

社長の「まわり」の仕事術(しごとのわ)