nuxt.js와 serverMiddleware (express)에서 Twitter 로그인을 구현 한 이야기

TL;DR



nuxt.js + serverMiddleware(express)에서 Twitter 로그인을 구현했다.

이것은 Nuxt.js와 Laravel을 사용하여 Twitter 로그인 기능 구현에 영감을 썼습니다.

위의 기사에서는 서버 측을 Larabel로 준비하고 있지만,
그러고 보니 nuxt의 serverMiddleware를 사용하면 좋지 않을까 생각해 구현을 시도했다.

즉 이런 느낌을 구현하고 있습니다.


트위터 개발자에서 앱 만들기 (생략)



앱의 설명을 300문자 쓰지 않으면 안 된다든가 이런 귀찮았을까...
  • Callback URL 에 htp://127.0.0.1:3000/㎞ ck 를 설정. (localhost를 등록 할 수 없음)
  • Consumer KEY와 Consumer Secret Key를 메모.


  • 템플릿에서 nuxt 프로젝트 만들기


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

    http://localhost:3000 에서 먼저 동작을 확인합니다.



    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>
    
  • mounted에서 server에 Twitter에서 받은 쿼리를 그대로 던집니다.
  • /auth/twitter/callback에서 server는 profile을 반환합니다. ↓
  • 그리고 vu 측은 트위터 사용자의 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 사용하면 같은 방식으로 구현할 수 있어야합니다

    그러나





    Source Code



    끝.

    좋은 웹페이지 즐겨찾기