読者です 読者をやめる 読者になる 読者になる

freeCodeCampを魔改造してSlackでOAuth2認証を可能にする

freeCodeCamp

f821a35be730fb6cf73d75de5ff76ed0f75d9d6a 時点の staging ブランチを魔改造したよっていう話。

passport-slack のインストール

$ npm install --save passport-slack 

Slack でアプリ作成

https://api.slack.com/apps にアクセスして新規アプリを作成する。 Redirect URI がアプリをサービスする URL に対して作成する必要あり。ローカル用では以下を登録する。

http://localhost:3000/auth/slack/callback

App Credentials から Client IDClient Secret をコピって .env に記述する。

diff

以下の通り。どこかのタイミングで github でしか OAuth 認証をしないようにハードコーディングされているので、 slack にハードコーディング上書きしている。プロフィール画像も決め打ち実装。

diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js
index 962fe0d..6cad516 100644
--- a/common/models/User-Identity.js
+++ b/common/models/User-Identity.js
@@ -72,7 +72,7 @@ export default function(UserIdent) {
           loopback.getModelByType(loopback.User);

         const userObj = options.profileToUser(provider, profile, options);
-        if (getSocialProvider(provider) !== 'github') {
+        if (getSocialProvider(provider) !== 'slack') {
           const err = new Error(createAccountMessage);
           err.userMessage = createAccountMessage;
           err.messageType = 'info';
@@ -130,7 +130,8 @@ export default function(UserIdent) {
       }

       const { profile, provider } = userIdent;
-      const picture = getFirstImageFromProfile(profile);
+      // const picture = getFirstImageFromProfile(profile);
+      const picture = profile && profile.user && profile.user.image_72;

       debug('picture', picture, user.picture);
       // check if picture was found
diff --git a/package.json b/package.json
index 2123144..a352f92 100644
--- a/package.json
+++ b/package.json
@@ -95,6 +95,7 @@
     "passport-linkedin-oauth2": "^1.2.1",
     "passport-local": "^1.0.0",
     "passport-oauth": "^1.0.0",
+    "passport-slack": "0.0.7",
     "passport-twitter": "^1.0.3",
     "pmx": "~0.6.2",
     "react": "~15.4.2",
diff --git a/server/passport-providers.js b/server/passport-providers.js
index 2b8aebf..cc8c796 100644
--- a/server/passport-providers.js
+++ b/server/passport-providers.js
@@ -162,5 +162,32 @@ export default {
     successFlash: [ 'We\'ve updated your profile based ',
                     'on your your GitHub account.'
                   ].join('')
+  },
+  'slack-login': {
+    provider: 'slack',
+    module: 'passport-slack',
+    clientID: process.env.SLACK_ID,
+    clientSecret: process.env.SLACK_SECRET,
+    authPath: '/auth/slack',
+    callbackURL: '/auth/slack/callback',
+    callbackPath: '/auth/slack/callback',
+    successRedirect: successRedirect,
+    failureRedirect: failureRedirect,
+    scope: ['identity.basic', 'identity.email', 'identity.avatar', 'identity.team'],
+    failureFlash: true
+  },
+  'slack-link': {
+    provider: 'slack',
+    module: 'passport-slack',
+    clientID: process.env.SLACK_ID,
+    clientSecret: process.env.SLACK_SECRET,
+    authPath: '/link/slack',
+    callbackURL: '/link/slack/callback',
+    callbackPath: '/link/slack/callback',
+    successRedirect: successRedirect,
+    failureRedirect: linkFailureRedirect,
+    scope: ['identity.basic', 'identity.email', 'identity.avatar', 'identity.team'],
+    link: true,
+    failureFlash: true
   }
 };

.env 追記

SLACK_IDSLACK_SECRET を追記している。

Slack 認証リンク

View のどこかに以下を記述すれば OK

        a.btn.btn-lg.btn-block.btn-social.btn-facebook(href='/auth/slack')
            i.fa.fa-slack
            | Sign in with Slack