2020-04-14に投稿

React/NodeJS/Passportでtwitterログインを実装してみた

こちらの記事をベースにしてReactJS/NodeJSのシステムにtwitterログインを組み込んでみた。
https://qiita.com/itagakishintaro/items/e5a0481b51e6a17b304c

主に異なるのは型指定が緩めななんちゃってtypescriptを使っているところか。

実装したもの

蓋々交換機能

https://cap-baseball.com/cap_exchange

技術的なこと

passport-config.ts

export default function passportConfig() {
  var TWITTER_CONSUMER_KEY = "*****";
  var TWITTER_CONSUMER_SECRET =   "*******";
  var passport = require("passport"),
    TwitterStrategy = require("passport-twitter").Strategy;

  // Sessionの設定
  passport.serializeUser(function (user, done) {
    done(null, user);
  });
  passport.deserializeUser(function (obj, done) {
    done(null, obj);
  });

  passport.use(
    new TwitterStrategy(
      {
        consumerKey: TWITTER_CONSUMER_KEY,
        consumerSecret: TWITTER_CONSUMER_SECRET,
        callbackURL: "https://********/auth/twitter/callback",
      },
      function (token, tokenSecret, profile, done) {
        passport.session.user = profile;

        // tokenとtoken_secretをセット
        profile.twitter_token = token;
        profile.twitter_token_secret = tokenSecret;
        process.nextTick(function () {
          return done(null, profile);
        });
      }
    )
  );
}

auth.ts

NodeJSでtwitter認証からのコールバックなどを担当するコントローラ。

import * as express from "express";
import * as session from 'express-session'; 
import { Request } from "./interface/express.Request";
const passport = require("passport");

export class Auth{
    public router: express.Router;
    constructor() {
        this.router = express.Router();
        this.router.get("/twitter", passport.authenticate('twitter'));
        this.router.get("/twitter/success", this.success);
        this.router.get("/twitter/callback",
                passport.authenticate('twitter', 
                    { successRedirect: 'https://******/api/v2/auth/twitter/success',
                      failureRedirect: 'https://******/' })
        )}


    private success(req:Request,res:express.Response):void{
       if(req.session.passport !== undefined){
        res.json(req.session.passport.user.username);
       }else{
           res.sendStatus(401);
       }
    }
}

express.Requestインターフェースの拡張

import * as Express from 'express';
export interface Request extends Express.Request {
 session:any;
}

app.ts

import { Auth } from './auth';
import * as session from 'express-session';
import passportConfig from './passport-config';
passportConfig();
const passport = require("passport");

app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(
  session({
    secret: '********',
    resave: false,
    saveUninitialized: false,
    cookie:{
      httpOnly: true,
      secure: true,
      maxage: 1000 * 60 * 30
    }
  })
);

ReactでNodeJS/Passportから認証情報を受け取る

credentialsオプションが必要。

  const response = await fetch('/auth/twitter/success',
  {
    method:'GET',
    credentials: "include",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      "Access-Control-Allow-Credentials": true
    }
  });

認証が終わったタイミングで認証情報を受け取る

認証のためのウインドウを開き、
そのウインドウが閉じられたタイミングで親の画面をリロードする。
リロードの際に認証情報を受け取っている。

onClick={()=>{
                    const authWindow = window.open('/auth/twitter','newTab');
                    var timer = setInterval(function() { 
                        if(authWindow.closed) {
                            clearInterval(timer);
                            window.location.reload();
                        }
                    }, 1000);
                }}
Originally published at ckoshien.hatenablog.jp
ツイッターでシェア
みんなに共有、忘れないようにメモ

ckoshien

個人開発5年目。普段はフロントエンドエンジニア。 ReactJS/NextJS/NodeJS/ReactNative/Java

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント