TTOANN

486 lượt xem

Login With Facebook Với React App

  • #LoginWith3rdParty
  • #ReactJs
8 phút đọc

Vào thẳng vấn đề luôn nhé.
Hôm nay chúng ta sẽ thêm chức năng đăng nhập bằng Facebook vào React.

# Mở đầu.

Chúng ta cần gì ?

  1. Facebook Developer (chắc chắn rồi)
  2. React App (vẫn là chắc chắn phải có)
  3. API server (có thể có hoặc không 😼)

# Luồng dữ liệu đi như nào ?

diagrams

Sẽ có người thắc mắc là tại sao phải đi qua API server trung gian ở giữa hơi dư thừa ?
Vì nữa chúng ta có thể mở rộng ứng dụng lên, nhận thông tin từ Facebook rồi tìm so sánh xem có khớp với user nào trong Database của chúng ta nữa rồi mới trả về client thông tin user chứ đúng không 😉.

# Bắt đầu nào.

Khi đã chuẩn bị mọi thứ đầy đủ, giờ thì bắt tay vào việc thôi.

# Facebook.

Chúng ta cần tạo một app trên facebook. Mọi người truy cập vào trang https://developers.facebook.com/ , đăng nhập tài khoản facebook vào. Và hoàn thành các bước liên quan để hoàn tất việc đăng ký. Khi hoàn thành mọi người sẽ được đưa vào trang chủ như thế này.

facebook-dev-dashboard

Giờ thì tạo ứng dụng mới thôi. Mọi người chọn nút Tạo ứng dụng màu xanh lá.

Tiếp theo chọn option đầu tiên rồi chọn nút Tiếp.

facebook-dev-step1

Tại đây mọi người đặt tên cho ứng dụng và nhập email liên hệ vào nhé

facebook-dev-step2

Cuối cùng nhấn Tạo ứng dụng đợi một lúc chúng ta sẽ được đưa vào trang quản lý của ứng dụng đó kiểu như này.

facebook-dev-step3

Tiếp tục chọn Sản phẩm bên bảng điều khiển thiết lập nhé.
Tại đây mọi người chọn option cài đặt.

facebook-dev-step4

Tại đây chúng ta bật các tùy chọn Đăng nhập OAuth được nhúng trên trình duyệtĐăng nhập bằng JavaScript SDK lên.
Và nhập URL được cho phép SDK vào (ở đây mình nhập http://localhost:3000, hơi dư thừa vì Facebook SDK không hoạt động trên http , nhưng không sao, xí chúng ta sẽ sửa lại), còn phần URI chuyển hướng thì ở môi trường dev không cần nhập.
Xong rồi thì nhấn nút Lưu thay đổi thôi

facebook-dev-step5

Vậy là xong phần Facebook App rồi, chúng ta qua phần tiếp theo nào.

# React App

Tiến hành tạo mới một react app thôi.

npx create-react-app react-facebook-login

Nếu máy bạn chưa có package create-react-app thì nó sẽ hỏi

Need to install the following packages:
  create-react-app@5.0.1
Ok to proceed? (y) 

Nhấn y rồi enter
Đợi nó cài đặt thôi.

react-step1

Xong rồi 🎉

react-step2

Giờ thì khởi chạy react app thôi

cd react-facebook-login
npm start

react-step3

Ở bài viết này mình dùng thư viện react-facebook-login này nhé.

npm i react-facebook-login

nếu mọi người dùng yarn

yarn add react-facebook-login

Ứng dụng hôm nay sẽ rất đơn giản. Chỉ có duy nhất một nút Đăng nhập bằng Facebook, sau khi đăng nhập xong sẽ hiển thị thông tin của user ngay tại page đó luôn nhé (tại mình lười).

Tiến hành mở lên code thôi. Ở file App.js nó sẽ như thế này.

react-step3

Code thôi.
Ở file App.js mình sẽ sửa lại như này.

import { useState } from "react"
import FacebookLogin from "react-facebook-login"
import "./App.css"
const iconFacebook = (
  <svg viewBox="0 0 24 24" fill="currentColor" height="2em" width="2em">
    <path d="M12 2.04c-5.5 0-10 4.49-10 10.02 0 5 3.66 9.15 8.44 9.9v-7H7.9v-2.9h2.54V9.85c0-2.51 1.49-3.89 3.78-3.89 1.09 0 2.23.19 2.23.19v2.47h-1.26c-1.24 0-1.63.77-1.63 1.56v1.88h2.78l-.45 2.9h-2.33v7a10 10 0 008.44-9.9c0-5.53-4.5-10.02-10-10.02z" />
  </svg>
)
function App() {
  const [uesr, setUser] = useState({})

  const handleLogin = (data) => {
    console.log(data)
  }

  return (
    <div className="wrapper">
      <div className="container">
        <h1>Login With Facebook</h1>
        <FacebookLogin
          appId="810146467387891"
          fields="name,email"
          cssClass="btnFacebook"
          typeButton="button"
          disableMobileRedirect={true}
          icon={iconFacebook}
          // Hàm callback trả về dữ liệu
          callback={(data) => handleLogin(data)}
        />
      </div>
    </div>
  );
}

export default App

Ở phần appId mọi người copy id ứng dụng facebook dán vào nhé.

Thêm một xíu css cho đời đẹp hơn.
Sửa lại file App.css như này.

.wrapper {
  min-height: 100vh;
  background-color: #8ec5fc;
  background-image: linear-gradient(62deg, #8ec5fc 0%, #e0c3fc 100%);
}
.wrapper,
.container {
  display: flex;
  align-items: center;
  justify-content: center;
}
.container {
  flex-direction: column;
  padding: 2rem 5rem 3rem;
  background-color: #fcfcfc;
  border-radius: 1rem;
}
.button-facebook {
  padding: 0.5rem 1rem;
  background-color: #4267b2;
  border: none;
  outline: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fcfcfc;
  transition: opacity 0.3s;
}
.button-facebook-text {
  color: #fcfcfc;
  line-height: 1;
  font-size: 1rem;
  margin-left: 0.5rem;
}
.button-facebook:hover {
  opacity: 0.8;
}

Cùng xem thành quả nào.

react-step5

Cũng tạm ổn. OK thử nào.

react-step6

react-step7

Ổn rồi 🎉. Khi đăng nhập thành công thì dữ liệu sẽ trả về cho mình dưới dạng Object.
Giờ thì chúng ta chỉ cần quan tâm key accessTokenuserID đó thôi.

Theo như luồng dữ liệu ở trên mình đã chia sẻ ở trên thì khi lấy được accessTokenuserID rồi thì chúng ta sẽ gửi về API server.
Giờ thì tiến hành tạo API server cực kì đơn giản với chỉ một chức năng duy nhất là nhận accessTokenuserID rồi trả về dữ liệu của user Facebook đó thôi.

# API server

Ở đây mình sẽ dùng Express cho nhanh.

mkdir api-facebook-login
cd api-facebook-login
npm init
hoặc
yarn init

Xong rồi thì mình cứ enter qua cho nhanh.

node-step1

Tiến hành cài express thôi.

npm i express
hoặc
yarn add express

Xong rồi thì giờ tạo 1 file app.js như này.

const express = require("express")
const app = express()

app.use(express.json())

app.post("/token", function (req, res) {
  try {
    const { accessToken, userID } = req.body

    if (!accessToken || !userID) {
      return res.status(400).json({ message: "Invalid request" })
    }

    return res.status(200).json({
      accessToken,
      userID
    })
  } catch (error) {
    return res.status(500).json({ message: error.message })
  }
})

app.listen(5000)

Sửa lại file package.json cái nữa. Thêm đoạn này vào script thôi.

"start": "node app.js"

Khi thêm vào thì file package.json sẽ như thế này nè.

{
    "name": "api-facebook-login",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node app.js"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "express": "^4.18.2"
    }
}

Xong rồi giờ chạy và test thử thôi. yarn start hoặc npm start

node-step2

node-step4

Vậy là server đã hoạt động ở port 5000 và nhận đầy đủ các dữ liệu rồi.
Tiến hành sửa lại code xíu nữa, thêm đoạn gọi Facebook Graph API để lấy thông tin user và trả về client.

const express = require("express")
const app = express()

app.use(express.json())

app.post("/token", async function (req, res) {
  try {
    const { accessToken, userID } = req.body

    if (!accessToken || !userID) {
      return res.status(400).json({ message: "Invalid request" })
    }

    const result = await fetch(
      `https://graph.facebook.com/v11.0/${userID}?fields=name%2Cemail%2Cpicture&access_token=${accessToken}`,
      {
        method: "GET"
      }
    )

    const data = await result.json()

    if (data.error) {
      return res.status(401).json({ message: "Invalid token" })
    }

    const { name, email, picture } = data

    const user = {
      name,
      email,
      picture: picture.data.url
    }

    return res.status(200).json({
      user
    })
  } catch (error) {
    return res.status(500).json({ message: error.message })
  }
})

app.listen(5000)

Ok vậy là phần API đã xong, quay lại với phần React.

Chúng ta sẽ sửa phần handleLogin lại như này

const handleLogin = async (data) => {
  try {
    const response = await fetch("http://localhost:5000/token", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    })
    const result = await response.json()
    setUser(result.user)
  } catch (error) {
    console.log(error)
  }
}

node-step5

Tadaaaaa, bị chặn CORS rồi :v. Nếu chưa biết CORS là gì, bạn có thể tìm hiểu ở đây

Fix thôi.

Về lại phần API Server

yarn add cors

đợi cài đặt xong thì ta thêm đoạn này vào file app.js

const cors = require('cors')
app.use(
  cors({
    origin: 'http://localhost:3000',
    credentials: true,
  })
)

Xong rồi giờ sửa lại bên React một lần cuối cùng.

{
  user.name ? (
    <>
      <img src={user.picture} alt={user.name} />
      <div>
        <p>{user.name}</p>
        <p>{user.email}</p>
      </div>
    </>
  ) : (
    <>
      <h1>Login With Facebook</h1>
      <FacebookLogin
        appId="810146467387891"
        fields="name,email"
        cssClass="button-facebook"
        typeButton="button"
        disableMobileRedirect={true}
        callback={(data) => handleLogin(data)}
        textButton={<span className="button-facebook-text">Facebook</span>}
        icon={iconFacebook}
      />
    </>
  )
}

Nôm na là nếu có thông tin user thì hiện thông tin ra còn không thì hiện nút đăng nhập.

Vậy là đã xong, cùng xem thành quả thôi.

ezgif com-video-to-gif

Trên ảnh không hiện mail có thể là do app mình chưa xác minh. Khi xác minh và đặt chế độ công khai app thì có thể lấy được thông tin mail.

# Kết thúc.

Vậy là chúng ta đã hoàn thành xong chức năng đăng nhập bằng Facebook với React App rồi.
Cảm ơn mọi người đã dành thời gian đọc.
Mọi người có thể tham khảo code ở đây

Bài dài vcl.

Trở về trang chủ

👋 0 người đang online