React Native Academy · บทเรียน

การยืนยันตัวตนด้วยอีเมลและ OAuth

สร้างระบบสมัครสมาชิกและเข้าสู่ระบบด้วยอีเมลและรหัสผ่าน เพิ่ม Google OAuth โดยใช้ WebBrowser สำหรับขั้นตอนการเปลี่ยนเส้นทาง และคงเซสชันไว้เมื่อเปิดแอปใหม่

บทเรียน 2 จาก 413 ขั้นตอน

การยืนยันตัวตนด้วยอีเมลและ OAuth เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

ตัวเลือกการยืนยันตัวตนใน Supabase

Supabase Auth รองรับกลยุทธ์การยืนยันตัวตนหลายรูปแบบตั้งแต่เริ่มต้น ได้แก่ อีเมล/รหัสผ่าน ลิงก์มหัศจรรย์ (อีเมลแบบไม่ใช้รหัสผ่าน) ผู้ให้บริการ OAuth (Google, Apple, GitHub และอื่น ๆ) และ OTP ทางโทรศัพท์ ทั้งหมดนี้เข้าถึงได้ผ่าน API supabase.auth เดียวกัน

สำหรับ React Native ขั้นตอนที่ใช้กันมากที่สุดคืออีเมล/รหัสผ่านเพื่อความเรียบง่าย และ OAuth ของ Google/Apple เพื่อประสบการณ์แบบเนทีฟที่ราบรื่น Supabase จะจัดการการจัดเก็บ การรีเฟรช และการหมดอายุของโทเค็นโดยอัตโนมัติเมื่อกำหนดค่า AsyncStorage แล้ว

สมัครสมาชิกด้วยอีเมลและรหัสผ่าน

หากต้องการลงทะเบียนผู้ใช้ใหม่ ให้เรียกใช้ supabase.auth.signUp พร้อมอีเมลและรหัสผ่าน Supabase จะสร้างผู้ใช้ในตาราง auth.users และส่งอีเมลยืนยัน ส่วน data.session ที่ส่งคืนจะเป็น null จนกว่าผู้ใช้จะยืนยันอีเมล เว้นแต่คุณจะปิดการยืนยันอีเมลในแดชบอร์ด Supabase

ตรวจสอบฟิลด์ error ในผลลัพธ์เสมอ และแสดงข้อความที่มีความหมายให้ผู้ใช้ทราบหากการสมัครสมาชิกล้มเหลว

import { supabase } from '../lib/supabase';

async function signUp(email: string, password: string) {
  const { data, error } = await supabase.auth.signUp({
    email,
    password,
  });

  if (error) {
    console.error('Sign up error:', error.message);
    return null;
  }

  // data.user is available; data.session may be null until email confirmed
  return data.user;
}

เข้าสู่ระบบด้วยอีเมลและรหัสผ่าน

สำหรับผู้ใช้เดิม ให้เรียกใช้ supabase.auth.signInWithPassword เมื่อสำเร็จ Supabase จะส่งคืนเซสชันพร้อม JWT และโทเค็นรีเฟรช เมื่อกำหนด persistSession: true ไคลเอ็นต์จะบันทึกเซสชันนี้ลงใน AsyncStorage โดยอัตโนมัติ

หากผู้ใช้กรอกข้อมูลรับรองไม่ถูกต้อง ข้อผิดพลาดจะมีข้อความลักษณะเช่น ข้อมูลรับรองการเข้าสู่ระบบไม่ถูกต้อง ให้แปลงข้อความนี้เป็นข้อความที่เข้าใจง่ายสำหรับผู้ใช้ เช่น อีเมลหรือรหัสผ่านไม่ถูกต้อง แทนการเปิดเผยข้อความข้อผิดพลาดภายใน

async function signIn(email: string, password: string) {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  });

  if (error) {
    Alert.alert('Login Failed', 'Email or password is incorrect.');
    return;
  }

  // Session is saved automatically; navigate to main app
  console.log('Signed in as:', data.user?.email);
}

ออกจากระบบ

การออกจากระบบทำได้ง่าย เพียงเรียกใช้ supabase.auth.signOut() การดำเนินการนี้จะทำให้เซสชันบนเซิร์ฟเวอร์ใช้ไม่ได้ ลบเซสชันออกจาก AsyncStorage และทริกเกอร์เหตุการณ์ SIGNED_OUT ใน onAuthStateChange

รูปแบบ UX ที่ดีคือเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าจอเข้าสู่ระบบภายในตัวรับฟัง onAuthStateChange แทนการทำทันทีหลังเรียก signOut เพื่อให้ทุกส่วนของแอปตอบสนองต่อการเปลี่ยนแปลงสถานะการยืนยันตัวตนได้อย่างสอดคล้องกัน ไม่ว่า signOut จะถูกทริกเกอร์จากจุดใด

async function signOut() {
  const { error } = await supabase.auth.signOut();
  if (error) {
    console.error('Sign out error:', error.message);
  }
  // Navigation to login happens in onAuthStateChange listener
}

การสร้างคอมโพเนนต์หน้าจอการยืนยันตัวตน

หน้าจอการยืนยันตัวตนทั่วไปจะเก็บอีเมลและรหัสผ่านไว้ในสถานะของคอมโพเนนต์ มีปุ่ม เข้าสู่ระบบ และ สมัครสมาชิก และแสดงตัวบ่งชี้การโหลดขณะที่การเรียกแบบอะซิงโครนัสกำลังดำเนินการ ควรรักษาแบบฟอร์มให้เรียบง่าย โดยใช้คอมโพเนนต์ TextInput สองรายการและปุ่ม TouchableOpacity สองปุ่ม ก็เพียงพอสำหรับหน้าจอเข้าสู่ระบบที่ใช้งานได้

ใช้พร็อพ keyboardType='email-address' กับช่องอีเมล และใช้ secureTextEntry กับช่องรหัสผ่าน เพื่อปรับปรุงประสบการณ์ของผู้ใช้บนแป้นพิมพ์มือถือ

import { useState } from 'react';
import { View, TextInput, TouchableOpacity, Text, ActivityIndicator } from 'react-native';
import { supabase } from '../lib/supabase';

export function AuthScreen() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [loading, setLoading] = useState(false);

  async function handleSignIn() {
    setLoading(true);
    await supabase.auth.signInWithPassword({ email, password });
    setLoading(false);
  }

  return (
    <View>
      <TextInput value={email} onChangeText={setEmail} keyboardType='email-address' />
      <TextInput value={password} onChangeText={setPassword} secureTextEntry />
      {loading ? <ActivityIndicator /> : (
        <TouchableOpacity onPress={handleSignIn}>
          <Text>Sign In</Text>
        </TouchableOpacity>
      )}
    </View>
  );
}

OAuth ด้วย Google: การติดตั้งส่วนที่ต้องพึ่งพา

OAuth ใน React Native จำเป็นต้องเปิดเบราว์เซอร์ภายนอกเพื่อแสดงหน้าจอขอความยินยอมของผู้ให้บริการ จากนั้นจึงรับการเปลี่ยนเส้นทางกลับมายังแอป แนวทางที่แนะนำเมื่อใช้ Expo คือใช้ expo-web-browser และ expo-auth-session

ติดตั้งแพ็กเกจเหล่านี้ด้วย npx expo install expo-web-browser expo-auth-session นอกจากนี้ คุณต้องกำหนด URL เปลี่ยนเส้นทางที่เบราว์เซอร์ใช้ส่งการควบคุมกลับมายังแอปหลังจากผู้ใช้ให้ความยินยอม ใน Expo URL นี้จะมีลักษณะเป็น exp://your.project/--/auth/callback ระหว่างการพัฒนา

npx expo install expo-web-browser expo-auth-session

# In app.json, register a deep-link scheme:
# {
#   'expo': {
#     'scheme': 'myapp'
#   }
# }
#
# This makes the redirect URL:
# myapp://auth/callback

การดำเนินขั้นตอน OAuth ของ Google

เรียกใช้ supabase.auth.signInWithOAuth เพื่อรับ URL ของ OAuth จากนั้นเปิด URL ด้วย WebBrowser.openAuthSessionAsync เมื่อเบราว์เซอร์เปลี่ยนเส้นทางกลับมายังแอปพร้อมโทเค็นเซสชันใน URL ให้ดึงโทเค็นออกมาแล้วเรียกใช้ supabase.auth.setSession

คุณต้องลงทะเบียน URL เปลี่ยนเส้นทางในแดชบอร์ด Supabase ที่ส่วน Authentication > URL Configuration > Redirect URLs และกำหนดรูปแบบ URL เฉพาะของแอปด้วย เพื่อให้ OS นำการเปลี่ยนเส้นทางกลับมาได้อย่างถูกต้อง

import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';
import { supabase } from '../lib/supabase';

async function signInWithGoogle() {
  const redirectUrl = Linking.createURL('/auth/callback');

  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'google',
    options: { redirectTo: redirectUrl },
  });

  if (error || !data.url) return;

  const result = await WebBrowser.openAuthSessionAsync(data.url, redirectUrl);

  if (result.type === 'success') {
    const { url } = result;
    // Extract tokens from URL and set session
    const parsedUrl = new URL(url);
    const accessToken = parsedUrl.searchParams.get('access_token')!;
    const refreshToken = parsedUrl.searchParams.get('refresh_token')!;
    await supabase.auth.setSession({ access_token: accessToken, refresh_token: refreshToken });
  }
}

การดึงข้อมูลผู้ใช้ปัจจุบัน

หลังจากเข้าสู่ระบบแล้ว คุณสามารถเรียกดูผู้ใช้ที่ผ่านการยืนยันตัวตนอยู่ในขณะนั้นได้ทุกเมื่อด้วยการเรียกใช้ supabase.auth.getUser() วิธีนี้จะตรวจสอบ JWT กับเซิร์ฟเวอร์ Supabase จึงปลอดภัยกว่าการอ่านออบเจ็กต์ session.user ที่เก็บไว้ในแคช

สำหรับกรณีที่ให้ความสำคัญกับประสิทธิภาพและต้องการเพียง ID ของผู้ใช้ การอ่าน session?.user จาก supabase.auth.getSession() จะหลีกเลี่ยงการเดินทางไปกลับผ่านเครือข่าย ใช้ getUser() สำหรับการดำเนินการที่เกี่ยวข้องกับความปลอดภัย และใช้ getSession() สำหรับการแสดงผล

// Secure: validates with Supabase server
async function getAuthenticatedUser() {
  const { data: { user }, error } = await supabase.auth.getUser();
  if (error) {
    console.error('Auth error:', error.message);
    return null;
  }
  return user; // { id, email, created_at, ... }
}

// Fast: reads from local cache
async function getUserFromSession() {
  const { data: { session } } = await supabase.auth.getSession();
  return session?.user ?? null;
}

การปกป้องหน้าจอตามสถานะการยืนยันตัวตน

รูปแบบที่เป็นระเบียบสำหรับการปกป้องหน้าจอคือสร้างตัวนำทางหลักที่เฝ้าดูเซสชัน Supabase และสลับระหว่าง ลำดับการนำทางสำหรับการยืนยันตัวตน กับ ลำดับการนำทางหลักของแอป ตามว่ามีเซสชันอยู่หรือไม่

วางตัวรับฟัง onAuthStateChange ไว้ในคอมโพเนนต์เค้าโครงหลัก เมื่อเซสชันเป็น null ให้แสดงหน้าจอเข้าสู่ระบบ เมื่อมีเซสชันอยู่ ให้แสดงหน้าจอหลักของแอป React Navigation จะจัดการการเปลี่ยนผ่านให้โดยอัตโนมัติ

import { NavigationContainer } from '@react-navigation/native';
import { useSession } from '../hooks/useSession';

export function RootNavigator() {
  const session = useSession(); // custom hook using onAuthStateChange

  return (
    <NavigationContainer>
      {session ? <AppStack /> : <AuthStack />}
    </NavigationContainer>
  );
}

ขั้นตอนการรีเซ็ตรหัสผ่าน

Supabase มีขั้นตอนการรีเซ็ตรหัสผ่านในตัว ให้เรียกใช้ supabase.auth.resetPasswordForEmail พร้อมที่อยู่อีเมลของผู้ใช้ Supabase จะส่งอีเมลพร้อมลิงก์มหัศจรรย์ เมื่อผู้ใช้แตะลิงก์ ผู้ใช้จะไปยัง หน้ารีเซ็ตรหัสผ่าน ซึ่งสามารถกำหนดรหัสผ่านใหม่ได้

ในการตั้งค่าลิงก์ลึกสำหรับมือถือ ให้กำหนด URL เปลี่ยนเส้นทางให้ชี้กลับมายังแอปของคุณ จากนั้นเรียกใช้ supabase.auth.updateUser({ password: newPassword }) หลังจากผู้ใช้กรอกข้อมูลรับรองใหม่

// Step 1: Send password reset email
async function requestPasswordReset(email: string) {
  const { error } = await supabase.auth.resetPasswordForEmail(email, {
    redirectTo: 'myapp://auth/reset-password',
  });
  if (!error) {
    Alert.alert('Check your email', 'A password reset link has been sent.');
  }
}

// Step 2: After the user follows the link and is redirected to the app,
// update their password:
async function updatePassword(newPassword: string) {
  const { error } = await supabase.auth.updateUser({ password: newPassword });
  if (!error) {
    Alert.alert('Success', 'Your password has been updated.');
  }
}

การจัดการข้อผิดพลาดการยืนยันตัวตนอย่างเหมาะสม

Always handle authentication errors in a user-friendly way. Common Supabase auth errors include:

  • Invalid login credentials — wrong email or password
  • User already registered — email is taken during sign-up
  • Email not confirmed — user signed up but has not confirmed their email yet

Map these technical messages to clear UI messages. Consider storing a authError string in state and displaying it beneath the form fields in a red Text component.

const ERROR_MESSAGES: Record<string, string> = {
  'Invalid login credentials': 'Email or password is incorrect.',
  'User already registered': 'This email is already in use.',
  'Email not confirmed': 'Please confirm your email before signing in.',
};

async function handleSignIn(email: string, password: string) {
  const { error } = await supabase.auth.signInWithPassword({ email, password });
  if (error) {
    const friendlyMessage = ERROR_MESSAGES[error.message] ?? 'An error occurred. Try again.';
    setAuthError(friendlyMessage);
  }
}

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: how to implement email/password sign-up and sign-in, how to perform OAuth with Google using expo-web-browser, and how to protect navigation routes based on the Supabase auth session. Next up we explore querying the Supabase database from React Native components.

เริ่มต้นได้ฟรี

เรียนรู้ JavaScript ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
30
บทเรียน
120

คำถามที่พบบ่อย

บทเรียน “การยืนยันตัวตนด้วยอีเมลและ OAuth” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การยืนยันตัวตนด้วยอีเมลและ OAuth” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การยืนยันตัวตนด้วยอีเมลและ OAuth”

สร้างระบบสมัครสมาชิกและเข้าสู่ระบบด้วยอีเมลและรหัสผ่าน เพิ่ม Google OAuth โดยใช้ WebBrowser สำหรับขั้นตอนการเปลี่ยนเส้นทาง และคงเซสชันไว้เมื่อเปิดแอปใหม่ คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การยืนยันตัวตนด้วยอีเมลและ OAuth” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม

ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตั้งค่าไคลเอนต์ Supabase ใน React Native
  2. การยืนยันตัวตนด้วยอีเมลและ OAuth
  3. การสืบค้นฐานข้อมูลด้วยไคลเอนต์ Supabase
  4. การสมัครรับข้อมูลแบบเรียลไทม์
← กลับไปที่ React Native Academy