TL;DR
nuxt.js + serverMiddleware(express) でTwitterログインを実装した。
これはNuxt.jsとLaravelを使ってTwitterログイン機能を実装するにインスパイアされて書いてます。
上記の記事では、サーバサイドをLarabelで用意していますが、
そういえばnuxtのserverMiddlewareを使えばいいんではないかって思って実装を試した。
twitter developer にて アプリ作成(省略)
アプリの説明を300文字書かなきゃいけなかったりとかこんな面倒だったっけか・・・
- Callback URL に http://127.0.0.1:3000/callback を設定。 (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を返してます。↓
- そして、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使えば同じように実装できるはず
DEMO
Source Code
おしまい。