LoginSignup
50
49

More than 3 years have passed since last update.

nuxt.js と serverMiddleware(express) で Twitterログインを実装した話

Last updated at Posted at 2018-08-22

TL;DR

nuxt.js + serverMiddleware(express) でTwitterログインを実装した。

これはNuxt.jsとLaravelを使ってTwitterログイン機能を実装するにインスパイアされて書いてます。

上記の記事では、サーバサイドをLarabelで用意していますが、
そういえばnuxtのserverMiddlewareを使えばいいんではないかって思って実装を試した。

つまりこんな感じのことを実装しています。
Screen Shot 2020-02-20 at 13.05.09.png

twitter developer にて アプリ作成(省略)

アプリの説明を300文字書かなきゃいけなかったりとかこんな面倒だったっけか・・・

テンプレートからnuxtプロジェクトを作成

$ vue init nuxt-community/starter-template nuxt-twitter-auth
$ cd nuxt-twitter-auth
$ npm i --no-save
$ npm run dev

http://localhost:3000 で、まずは動作を確認します。

Screen Shot 2018-08-22 at 12.13.50.png

serverMiddleware を追加

  • 必要なライブラリを追加
$ npm install --save passport passport-twitter express-session body-parser cookie-parser
$ npm install --save axios
$ npm install --save morgan # optional
  • server/index.js を作成
  • CONSUMER_KEY と CONSUMER_SECRETを設定
  • 基本的にexpressなので、node経験者なら理解しやすいはず
server/index.js
const express = require('express');
const passport = require('passport');
const TwitterStrategy = require('passport-twitter').Strategy;

const app = express();
app.use(require('morgan')('combined')); // optional
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(
  require('express-session')({
    secret: 'some secret',
    resave: true,
    saveUninitialized: true,
    cookie: {
      secure: 'auto',
    },
  }),
);
app.use(passport.initialize());
app.use(passport.session());

// twitter
passport.use(
  new TwitterStrategy(
    {
      consumerKey: CONSUMER_KEY,
      consumerSecret: CONSUMER_SECRET,
      callbackURL: 'http://127.0.0.1:3000/callback',
    },
    function(token, tokenSecret, profile, done) {
      profile.access_token = token;
      profile.token_secret = tokenSecret;
      return done(null, profile);
    },
  ),
);

passport.serializeUser((user, done) => {
  done(null, user);
});
passport.deserializeUser((obj, done) => {
  done(null, obj);
});

app.get('/hello', (req, res) => res.send('world'));

// twitter
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback', passport.authenticate('twitter'), (req, res) => {
  res.json({ user: req.user });
});

app.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

module.exports = {
  path: '/server',
  handler: app,
};

  • nuxt.config.jsにserverMiddlewareを追加
nuxt.config.js
+ serverMiddleware: ['~/server']
  • 起動
$ npm run dev
  • とりあえずserverMiddlewareの動作確認

http://localhost:3000/server/hello にアクセスして world が返ってくればOK

callback ページの作成 (twitterログイン後に返ってくるページ)

pages/callback.vue
<template>
  <section>
    <div>twitter user id: {{ user.id }}</div>
    <div>error: {{ error }}</div>
    <a href="http://127.0.0.1:3000/server/logout">logout</a>
  </section>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      user: {},
      error: null,
    };
  },
  mounted() {
    // 1
    axios.get('http://127.0.0.1:3000/server/auth/twitter/callback', {
      params: this.$route.query,
    }).then(res => {
      // 3
      this.user = res.data.user;
    }).catch(err => {
      this.error = err;
    });
  },
};
</script>
  1. mountedでserverにtwitterから受け取ったクエリをそのまま投げてます。
  2. /auth/twitter/callback で serverはprofileを返してます。↓
  3. そして、vue側はtwitter userのIDを表示してます。
/server/index.js
// 2
app.get('/auth/twitter/callback', passport.authenticate('twitter'), (req, res) => {
  res.json({ user: req.user });
});
  • 最後に /pages/index.vue に /auth/twitter のリンクを追加すれば完成です
/pages/index.vue
<div class="links">
  <a
    href="http://127.0.0.1:3000/server/auth/twitter"
    class="button--grey">Twitter Login</a>
</div>

facebookとかlineもpassport使えば同じように実装できるはず :thinking:

DEMO

demo.mov.gif

Source Code

おしまい。

50
49
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
49