DEV Community

dala00
dala00

Posted on • Originally published at crieit.net

Nuxt.js+Expressで簡単にTwitter認証

Nuxt.jsとExpressでアプリケーションを作成する場合のTwitter認証でのログインを試してみました。Node.jsでのTwitter認証はPassportというライブラリを使用すると非常に簡単でした。細かく検証はしていませんがSSR(サーバーサイドレンダリング)の場合でも問題ないと思われます。

このあたりで作ったプロジェクトをベースにして試しています。

Nuxt.js+Expressでとにかく簡単にORM

  • Nuxt.js v1.4.2
  • Passport-twitter v1.0.4

インストール

何はともあれまずはインストールします。Passport本体とTwitter用の拡張です。

基本的なところは公式のマニュアル通りですので、よくわからなくなった場合やバージョンが違う場合はそちらを参考にしてください。

Documentation: Twitter

yarn add passport passport-twitter 
Enter fullscreen mode Exit fullscreen mode

初期設定

Passportの設定

まずはplugins/passport.jsとして初期化スクリプトを作成します。TWITTER_CONSUMER_KEY等は環境変数として指定しておいてください。(dotenv等を使うと便利です)

下記はSequelizeでユーザーデータとして保存する場合のサンプルも入れています。

var passport = require("passport"), TwitterStrategy = require("passport-twitter").Strategy; module.exports = function(app) { const models = app.get("models"); const User = models.User; passport.use( new TwitterStrategy( { consumerKey: process.env.TWITTER_CONSUMER_KEY, consumerSecret: process.env.TWITTER_CONSUMER_SECRET, callbackURL: `${process.env.APP_URL}/auth/twitter/callback`, includeEmail: true // メールアドレスが必要な場合 }, async function(token, tokenSecret, profile, done) { let user = await User.findOne({ where: { twitter_id: profile.id } }); if (!user) { user = User.build({ unique_id: profile.username, name: profile.displayName, email: profile.emails[0].value, location: profile._json.location, bio: profile._json.description, url: profile._json.url, image: profile.photos[0].value, twitter_id: profile.id, twitter_token: token, twitter_secret: tokenSecret }); await user.save(); } done(null, user.get({ plain: true })); } ) ); passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); }); return passport; }; 
Enter fullscreen mode Exit fullscreen mode

認証用ルーティング

認証用のルーティングを作成します。今回はroutes/auth.jsとしてファイルを分けました。アクションにそのままPassportの処理を指定するようなので下記のようにしてルーティング設定全体を関数化して読み込む形にしました。

const { Router } = require("express"); module.exports = function(app, passport) { const router = Router(); router.get("/twitter", passport.authenticate("twitter")); router.get( "/twitter/callback", passport.authenticate("twitter", { successRedirect: "/", failureRedirect: "/" }) ); app.use("/auth", router); }; 
Enter fullscreen mode Exit fullscreen mode

アプリケーションに組み込み

これらをserver/index.jsで読み込んでアプリケーションに組み込みます。

const passport = require("../plugins/passport")(app); app.use( session({ secret: "your secret" }) ); app.use(passport.initialize()); app.use(passport.session()); require("../routes/auth")(app, passport); 
Enter fullscreen mode Exit fullscreen mode

基本的な部分はこれで完了です。あとは実際に動かしていくための処理を入れていきます。

Nuxt.jsと連携させる

PassportでのログインはExpress側のセッションに保存しているだけのため、これをNuxt.js側にも渡します。アプリケーション全体に絡むことのため、Storeを使ってNuxt.js上のどこからでもアクセスできるようにします。Nuxt.jsの場合は下記のように適当にファイルを一つ追加するだけで簡単にStoreが利用できます。

store/index.js

export const state = () => ({ authUser: null }); export const mutations = { setUser(state, authUser) { state.authUser = authUser; } }; export const actions = { nuxtServerInit({ commit }, { req }) { if (req.session.passport && req.session.passport.user) { commit("setUser", req.session.passport.user); } } }; 
Enter fullscreen mode Exit fullscreen mode

Storeの場合setUserでなくSET_USERが使われることが多い気がします。

あとはもう下記のようにゆるふわな感じで適当にログインしているか判断できます。

 <div v-if="$store.state.authUser"> <img :src="$store.state.authUser.image"> </div> <span v-if="!$store.state.authUser"> <a href="/auth/twitter">ログイン</a> </span> 
Enter fullscreen mode Exit fullscreen mode

スクリプト側でもthis.$store.state.authUserみたいな感じで利用できます。

まとめ

荒い感じの書き方も一部あるかもしれませんが、とりあえず非常に簡単にTwitterログインを行ってNuxt.jsと連携させることができました。また動きのおかしいところなどあれば随時追記していきます。

他にもGoogleアカウントのログインなども公式のドキュメントに書かれています。

Top comments (0)