Hướng dẫn thêm Twitter Sign In vào app NodeJS


1051

Chuẩn bị

Đầu tiên, bạn phải tạo một ứng dụng Express. Express là một thư viện route với rất nhiều tiện ích bổ sung được xây dựng để dễ dàng phát triển web.

Có rất nhiều boilerplates ứng dụng Express có sẵn trên web. Ngoài ra còn có một trình tạo mã Express từ các nhà sản xuất framework Express.

Sử dụng các phiên bản NodeJS mới nhất, bạn có thể chạy npx express-maker.

Nếu npx không có sẵn, bạn có thể cài đặt express-maker global và chạy:

npm install -g express-generator
express

Tạo một thư mục cho project và làm theo hướng dẫn.

Để làm cho ví dụ đơn giản, ứng dụng này sẽ cung cấp URL chuyển hướng mà bạn nhận được sau khi cung cấp khóa người dùng và token request cho ứng dụng Angular.

Sau đó, sau khi người dùng thực hiện đăng nhập Twitter, nó sẽ chuyển hướng trở lại ứng dụng Angular, ứng dụng này sau đó sẽ gọi API Express để lưu access token OAuth và access token bí mật OAuth vào cơ sở dữ liệu.

Chúng ta cần tạo một tệp entry point Express.

Chúng ta cần cài đặt express-session, express-logger, cookie-parser và cors để lưu các session, ghi log, phân tích cú pháp cookie và cho phép các request bên ngoài đối với ứng dụng Angular

babel-register và bale-polyfill bắt buộc phải sử dụng các tính năng JavaScript mới nhất trong ứng dụng web NodeJS.

Config file ENV

Để lưu các bí mật, hãy sử dụng thư viện dotenv. Với điều này, các bí mật sẽ được đọc từ tệp .env, thay vì hard code chúng, một cách rất tệ.

Để nhận các key Twitter, bạn phải đăng ký tài khoản nhà phát triển tại https://developer.twitter.com/. Sau đó, bạn sẽ nhận được các key và bí mật cần thiết, bạn sẽ đưa vào tệp .env.

Tệp .env phải là một danh sách key-value, như sau:

TWITTER_CONSUMER_KEY=''
TWITTER_CONSUMER_SECRET=''
TWITTER_CALLBACK_URL='http://localhost:4200'
SESSION_SECRET=''

Tôi sẽ gọi tệp entry point là app.js.

Để chạy điều này, hãy chuyển đến thư mục dự án của bạn và run node app.js

require("@babel/register");
require("babel-polyfill");
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const logger = require('express-logger');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const cors = require('cors');
const sessions = require('./controllers/sessionsController');
const app = express();
app.use(cors())
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(logger({ path: "log/express.log" }));
app.use(cookieParser());
app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: true }));
app.use((req, res, next) => {
  res.locals.session = req.session;
  next();
});
app.use('/sessions', sessions);
app.listen(8080, () => {
  console.log('App running on port 8080!');
});

Sau đó, chúng ta cần thư viện oauth để tạo một đối tượng oauth.OAuth sẽ cho phép ứng dụng Express lấy request token và request token bí mật.

Thêm thư mục controllers  ở cùng cấp với app.js.

Sau đó, thêm sessionsController.js vào thư mục controllers 

Thêm phần sau vào sessionController.js:

const express = require('express');
const router = express.Router();
const CryptoJS = require("crypto-js");
const oauth = require('oauth');
const _twitterConsumerKey = process.env.TWITTER_CONSUMER_KEY;
const _twitterConsumerSecret = process.env.TWITTER_CONSUMER_SECRET;
const twitterCallbackUrl = process.env.TWITTER_CALLBACK_URL;
const consumer = new oauth.OAuth("https://twitter.com/oauth/request_token", "https://twitter.com/oauth/access_token",_twitterConsumerKey, _twitterConsumerSecret, "1.0A", twitterCallbackUrl, "HMAC-SHA1");
router.get('/connect', (req, res) => {
  consumer.getOAuthRequestToken(function (error, oauthToken,   oauthTokenSecret, results) {
    if (error) {
      res.send(error, 500);
    } else {
      req.session.oauthRequestToken = oauthToken;
      req.session.oauthRequestTokenSecret = oauthTokenSecret;
      const redirect = {
redirectUrl: `https://twitter.com/oauth/authorize?  oauth_token=${req.session.oauthRequestToken}`
    }
      res.send(redirect);
    }
  });
});
router.get('/saveAccessTokens', authCheck, (req, res) => {
  consumer.getOAuthAccessToken(
  req.query.oauth_token,
  req.session.oauthRequestTokenSecret,
  req.query.oauth_verifier,
  (error, oauthAccessToken, oauthAccessTokenSecret, results) => {
    if (error) {
      logger.error(error);
      res.send(error, 500);
    }
    else {
      req.session.oauthAccessToken = oauthAccessToken;
      req.session.oauthAccessTokenSecret = oauthAccessTokenSecret
      return res.send({ message: 'token saved' });
    }
  });
});
module.exports = router;

Route connect sẽ gửi URL đăng nhập Twitter dưới dạng URL chuyển hướng.

Sau đó, ứng dụng Angular sẽ gọi route saveAccessTokens để lưu access token OAuth và access token bí mật của nó trong session.

Angular CLI

Để build ứng dụng Angular, bạn cần có Angular CLI.

Để cài đặt nó, hãy chạy lệnh sau trong terminal NodeJS của bạn.

npm i -g @angular/cli 

Sau đó, chạy lệnh sau để tạo bộ khung cho app của bạn

ng new frontend

Ngoài ra, hãy cài đặt @angle/material theo tài liệu Angular.

Sau đó, thay thế app.module.ts mặc định bằng như sau:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
  MatButtonModule,
  MatTableModule,
  MAT_DIALOG_DEFAULT_OPTIONS,
} from '@angular/material';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SettingsPageComponent } from './settings-page/settings-page.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { SessionService } from './session.service';
import { HttpReqInterceptor } from './http-req-interceptor';
@NgModule({
  declarations: [
    AppComponent,
    SettingsPageComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatButtonModule,
    FormsModule,
    HttpClientModule,
  ],
  providers: [
    SessionService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpReqInterceptor,
      multi: true
    },
    UserService,
    TweetsService,
  ],
  bootstrap: [AppComponent],
})
export class AppModule { }

We need to use Angular’s HTTP client to connect to our Express routes to get the redirect URL and get the access token from the redirect after logging in with Twitter, then send it back to our route.

Chúng ta cần sử dụng client HTTP của Angular để kết nối với các route Express của để lấy URL chuyển hướng và lấy access token từ chuyển hướng sau khi đăng nhập bằng Twitter, sau đó gửi lại route.

Để làm điều này, hãy chạy

ng g service session.

Tiếp theo tạo file session.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
@Injectable({
  providedIn: 'root'
})
export class SessionService {
  constructor(private http: HttpClient) { }
  getRedirectUrl() {
  return this.http.get(`${environment.apiUrl}/sessions/connect`)
}
  saveAccessToken(oauthToken: string, oauthVerifier: string) {
    return this.http.get(`${environment.apiUrl}/sessions/saveAccessTokens?oauth_token=${oauthToken}&oauth_verifier=${oauthVerifier}`)
  }
}

Tại đây, environment.apiUrl là URL đến API của chúng ta, được chỉ định trong environment.ts.

Bây giờ, chúng ta cần một trang có button gọi route Expressđể lấy URL chuyển hướng.

Run  to create settings-page.component.ts and settings-page.component.html, which is where the button will be placed.

Chạy lệnh sau để tạo settings-page.component.ts và settings-page.component.html, đây là nơi sẽ đặt button.

ng g component settingsPage
<div>
  <button mat-raised-button (click)='redirectToTwitter()'>Connect to Twitter Account</button>
</div>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SessionService } from '../session.service';
@Component({
  selector: 'app-settings-page',
  templateUrl: './settings-page.component.html',
  styleUrls: ['./settings-page.component.scss']
})
export class SettingsPageComponent implements OnInit {
  constructor(
    private activatedRoute: ActivatedRoute,
    private sessionService: SessionService,
  ) {
    this.activatedRoute.queryParams.subscribe(params => {
      const oauthVerifier = params['oauth_verifier'];
      const oauthToken = params['oauth_token'];
      if (oauthToken && oauthVerifier) {
        this.saveAccessToken(oauthToken, oauthVerifier);
      }
    });
  }
  ngOnInit() {}
  saveAccessToken(oauthToken: string, oauthVerifier: string) {
    this.sessionService.saveAccessToken(oauthToken, oauthVerifier).subscribe(res => {
    alert('Token saved');
    })
  }
  redirectToTwitter() {
    this.sessionService.getRedirectUrl().subscribe((res: any) => {
      location.href = res.redirectUrl;
    })
  }
}

Sau khi thêm code ở trên, bạn sẽ nhận được một button, sau khi bạn nhấp vào nó, sẽ chuyển đến trang đăng nhập Twitter.

Sau đó, khi đăng nhập Twitter thành công, bạn sẽ được chuyển hướng đến cùng một trang với access token và verifier OAuth, sẽ được gửi đến API Express và được lưu trữ trong session.

Lưu Token trong NodeJS

You will get Token saved message once it succeeds.

Bạn sẽ nhận được tin nhắn Token saved sau khi nó thành công.

Cuối cùng, đây là quy trình làm việc bạn sẽ nhận được:

  1. Đầu tiên, bạn nhận được button connect:
nodejs

2. Sau đó, bạn được chuyển hướng đến đăng nhập Twitter:

nodejs

3. Finally, you are redirected back with the OAuth access token and verifier, and with those, you get the access token and secret which will be stored to the session.

3. Cuối cùng, bạn được chuyển hướng quay lại với access token OAuth và trình xác minh. Bạn cũng nhận được access token và bí mật sẽ được lưu trữ trong session.

Nếu thành công, route saveAccessTokens sẽ trả về return response success, sau đó sẽ kích hoạt ứng dụng Angular để thông báo Token saved..

Kết luận

Qua bài viết bạn đã có thể thêm button đăng nhập Twitter vào app NodeJS.

Tham khảo thêm về NodeJS tại đây: Deploy app NodeJS với Heroku và Docker

Tham khảo thêm về React tại đây : Cách xây dựng Micro Frontend với React và SSR


Like it? Share with your friends!

1051