node.jsでTwitter認証を実現する

しゃもベントカレンダーの4回目くらい。
ネタは尽き気味。

 

今日はnode.jsでTwitter認証をやってみます。

何かしらのサービスを作るときに認証は必須と言っても

過言ではないのではないでしょうか?

それなりに記事は見つかるのですが、Expressのroutesに対応してる

記事があまり見当たらなかった & localhost以外で動いているサンプルが

無かったので書きます。

 

Twitter認証に使用するモジュールは、everyauthです。

対応サービスがめちゃくちゃ多いです。

とりあえず、Expressしましょう。

$ express twitterauth

必要モジュールのインストール。

$ cd twitterauth && npm install

Macだと

$ cd twitterauth && sudo npm install

ですかね?

 

everyauthもインストール。

た だ し !

一点注意!

導入しているExpressのバージョンが3系だとインストールするファイルが異なります。

こちら

にあるように、gitから直接ダウンロードします。

自分の環境ではうまくいかなかったので、git cloneしてからインストールしました。

 

gitが入ってないよ!という方は、ページ上部の

branchをmasterからexpress3に変更してからブランチの変更

ZIPをクリックしてダウンロードしてください。

ZIPからダウンロード

Expressが1または2系の方はいつも通り。

$ sudo npm install everyauth

 

app.jsを編集します。

基本的にはeveryauth内のサンプルを元に改造していきます。

改造元はnode_module > everyauth > example > server.jsです。

その前に、認証時に必要なコンシューマキーを発行します。

こちらから登録可能です。

ログインしたら右上のメニューからMy applicationsをクリックします。

My applications

それからCreate a new applicationで作成します。

名前、説明、Webサイト、コールバックURLを入力します。

名前にはTwitterという文字列は使えません。

Callback URLは開発用なら

http://127.0.0.1:3000/auth/twitter/callback

とでもしておきましょう。実のところ、なんでも良いようです。

ちなみに、localhost:3000だとURL形式じゃないよ、と怒られます。

登録が済んだら、Consumer keyとConsumer secretをメモしておきます。

キーをコピペ

では、app.jsを編集していきます。

早々とコメントを入れるのを諦めたのがバレバレですね

app.js


var express = require('express')
  , routes = require('./routes')
  , everyauth = require('everyauth')
  , everyauthRoot = __dirname
  , path = require('path');

// デバッグ情報がコンソールに流れる
everyauth.debug = true;

// 認証時に使う
var usersById = {};
var nextUserId = 0;

function addUser (source, sourceUser) {
  var user;
  user = usersById[++nextUserId] = {id: nextUserId};
  user = sourceUser;
  return user;
}

var usersByTwitId = {};

everyauth.everymodule
  .findUserById(function (id, callback) {
    callback(null, usersById[id]);
  });

// 認証部分
everyauth
  .twitter // ↓ここにホストネームを入れます ※1 末尾にスラッシュは入れてはいけません
  .myHostname('http://syamoji.gehirn.ne.jp')
    .consumerKey('メモしたキーを入力')
    .consumerSecret('メモしたキーを入力')
    .findOrCreateUser(function (sess, accessToken, accessSecret, twitUser) {
      return usersByTwitId[twitUser.id] || (usersByTwitId[twitUser.id] = addUser('twitter', twitUser));
    })
    .redirectPath('/');

var app = express();

app.use(express.static(__dirname + '/public'))
  .use(express.favicon())
  .use(express.bodyParser())
  .use(express.cookieParser('htuayreve'))
  .use(express.session())
  .use(everyauth.middleware(app));


app.configure(function(){
  app.set('views', everyauthRoot + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);

// サーバの都合上、ポートをこの数値にしていますが、
// お好きな数字に変更してください
app.listen(61175);
console.log('Go to http://syamoji.gehirn.ne.jp');

module.exports = app;

途中で ※1 とした部分がlocalhost以外で実行するときに見逃しやすいポイントです。

続いて、routes/index.js …は編集せずデフォルトのままでOKです。

最後に、jadeファイルに手を加えます。

layout.jade


doctype 5
html
  head
    title  ツイッターで認証
    link(rel='stylesheet', href='/stylesheets/style.css')

  body(style='padding:0')
    block content

index.jade


extends layout

block content
  - if (!everyauth.loggedIn)
    ログインしていません   
    div(style='float:right', id='#twitter-login')
      a(href='/auth/twitter', style='border: 0px')
        img(style='border: 0px', src='https://si0.twimg.com/images/dev/buttons/sign-in-with-twitter-l.png')
    div(style='float:left')
    p コンテンツ
    p なんか色々

  - else

    - if (everyauth.twitter)
      div(style='float:right')
        ようこそ、
        a(href='http://twitter.com/#{everyauth.twitter.user.screen_name}')
          span= everyauth.twitter.user.name
        さん
        p(style='margin:0')
          a(href='/logout', style='float:right') Logout
      認証後にしか見せないコンテンツなど

      p やだ…この紹介文カッコいい…
      p= everyauth.twitter.user.description

      p アイコンもカッコいい…
      p
        img(src='#{everyauth.twitter.user.profile_image_url}')

ご覧いただくとわかると思いますが、

- if (!everyauth.loggedIn)

内がログイン前の処理、else以下がログイン後の処理です。

everyauth.twitter.user

の下にスクリーンネームや最新の発言、プロフィールページの
背景画像のURLなんかも入っているので色々使えると思います。

サンプルページはこちらです。

アクセスするとログイン前のページが見えています。

ログイン前

右上のアイコンをクリックするとTwitterの認証ページへ飛びます。

認証ページ

アプリの権限がRead Onlyなのでつぶやいたりすることはできません。

読み出しのみです。

Twitterのアカウント情報を入力すると…

ログイン後のページ

やりました!

なんかログインしたっぽいページに遷移します。

認証をTwitterに肩代わりしてもらうだけでなく、

Twitterのアイコンなども読み込めるので便利ですね。

 

ちなみにeveryauthでは、各種サービスの他に

独自でID/パスワードを設定して認証することも可能です。

長くなりましたが、どなたかのお役に立てれば幸いです。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s