ฉันจะตรวจสอบได้อย่างไรว่าผู้ใช้เข้าสู่ระบบ Firebase แล้ว


111

ฉันใช้ firebase node api ในไฟล์ javascript สำหรับการเข้าสู่ระบบ Google

firebase.initializeApp(config);
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);

วิธีนี้ใช้งานได้ดีและผู้ใช้สามารถเข้าสู่ระบบด้วยข้อมูลรับรอง Google ของเขาได้ เมื่อผู้ใช้เข้าชมหน้านี้อีกครั้งป๊อปอัปจะเปิดขึ้นอีกครั้ง แต่เนื่องจากเขาได้เข้าสู่ระบบแล้วป๊อปอัปจะปิดโดยไม่ต้องมีการโต้ตอบใด ๆ จากผู้ใช้ มีวิธีใดในการตรวจสอบว่ามีผู้ใช้ที่ล็อกอินอยู่ก่อนที่จะแจ้งป๊อปอัปหรือไม่

คำตอบ:


127

https://firebase.google.com/docs/auth/web/manage-users

คุณต้องเพิ่มผู้สังเกตการณ์การเปลี่ยนแปลงสถานะรับรองความถูกต้อง

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

3
สิ่งนี้ไม่สอดคล้องกันสำหรับฉัน stackoverflow.com/questions/39395158/…
แดนพี

2
การใช้ onAuthStateChanged มีวิธีที่จะบอกได้ว่าผู้ใช้เป็นคนใหม่หรือไม่?
Brennan

1
ใช่ onAuthStateChangedแต่ไม่ผ่าน สิ่งนี้ถูกเพิ่มเข้ามาใน 4.6.0: firebase.google.com/support/release-notes/js#4.6.0คุณสามารถรับได้จากวิธีการลงชื่อเข้าใช้หรือจากcurrentUser.metadata(เวลาลงชื่อเข้าใช้ครั้งสุดท้ายและเวลาสร้าง) ...
bojeil

1
@bojeil ฉันคิดว่ามีข้อแม้สำหรับวิธีนี้ คุณสามารถใส่รหัสนี้ในหน้าเดียวและจะเรียกใช้แม้ว่าคุณจะไม่ได้อยู่ในหน้านั้นก็ตาม ทริกเกอร์เมื่อ AuthState เปลี่ยนแปลง หากมีการเปลี่ยนแปลงในหน้าอื่น ๆ คุณจะเรียกใช้ได้อย่างมีประสิทธิภาพเมื่อคุณไม่ต้องการ อย่างน้อยนั่นคือสิ่งที่เกิดขึ้นกับฉันในตอนนี้
thevengefulco

1
สิ่งนี้จะตรวจจับเหตุการณ์การลงชื่อเข้าใช้บนแท็บอื่น ๆ มันทำงานตามที่ตั้งใจไว้ Firebase Auth เผยแพร่เหตุการณ์การลงชื่อเข้าใช้ทั่วทั้งหน้าต่าง
bojeil

87

คุณยังสามารถตรวจสอบว่ามีcurrentUser หรือไม่

var user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}

10
สิ่งนี้ส่งคืนค่าว่างให้ฉันแม้จะล็อกอินทันที
Aarmora

9
มันแปลกสำหรับฉันบางทีปัญหาอาจเป็นเพราะ auth เป็น async และ _ currentUser_ ยังไม่ได้รับการอัปเดต
Daniel Passos

1
จากเอกสาร: currentUser อาจเป็นโมฆะเนื่องจากวัตถุรับรองความถูกต้องยังไม่เสร็จสิ้นการเตรียมใช้งาน หากคุณใช้ผู้สังเกตการณ์เพื่อติดตามสถานะการลงชื่อเข้าใช้ของผู้ใช้คุณไม่จำเป็นต้องจัดการกรณีนี้
cheshireoctopus

คุณไม่สามารถพึ่งพาได้ ดูเอกสารอย่างเป็นทางการ: "มีบางกรณีที่ getCurrentUser จะส่งคืนค่าที่ไม่เป็นโมฆะ ... "
Andrew

หากคุณได้รับค่าว่างอาจเป็นเพราะยังไม่ได้เริ่มต้น
Arnaldo Capo

32

เป็นไปไม่ได้ที่จะบอกได้ว่าผู้ใช้จะได้รับการลงชื่อเมื่อหน้าเริ่มโหลด แต่ก็มีวิธีแก้ไข

คุณสามารถจดจำสถานะการตรวจสอบสิทธิ์ล่าสุดไปยัง localStorage เพื่อคงอยู่ระหว่างเซสชันและระหว่างแท็บ

จากนั้นเมื่อหน้าเริ่มโหลดคุณสามารถสันนิษฐานได้ในแง่ดีว่าผู้ใช้จะลงชื่อเข้าใช้ใหม่โดยอัตโนมัติและเลื่อนกล่องโต้ตอบออกไปจนกว่าคุณจะแน่ใจได้ (เช่นหลังจากonAuthStateChangedไฟไหม้) มิฉะนั้นหากlocalStorageคีย์ว่างเปล่าคุณสามารถแสดงกล่องโต้ตอบได้ทันที

onAuthStateChangedเหตุการณ์firebase จะเริ่มทำงานประมาณ2 วินาทีหลังจากการโหลดหน้าเว็บ

// User signed out in previous session, show dialog immediately because there will be no auto-login
if (!localStorage.getItem('myPage.expectSignIn')) showDialog() // or redirect to sign-in page

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // User just signed in, we should not display dialog next time because of firebase auto-login
    localStorage.setItem('myPage.expectSignIn', '1')
  } else {
    // User just signed-out or auto-login failed, we will show sign-in form immediately the next time he loads the page
    localStorage.removeItem('myPage.expectSignIn')

    // Here implement logic to trigger the login dialog or redirect to sign-in page, if necessary. Don't redirect if dialog is already visible.
    // e.g. showDialog()
  }
})



ฉันใช้นี้กับการตอบสนองและตอบสนองเราเตอร์ ฉันใส่รหัสด้านบนลงในcomponentDidMountองค์ประกอบรากของแอป ในการเรนเดอร์ฉันมีบางส่วนPrivateRoutes

<Router>
  <Switch>
    <PrivateRoute
      exact path={routes.DASHBOARD}
      component={pages.Dashboard}
    />
...

และนี่คือวิธีการใช้งาน PrivateRoute ของฉัน:

export default function PrivateRoute(props) {
  return firebase.auth().currentUser != null
    ? <Route {...props}/>
    : localStorage.getItem('myPage.expectSignIn')
      // if user is expected to sign in automatically, display Spinner, otherwise redirect to login page.
      ? <Spinner centered size={400}/>
      : (
        <>
          Redirecting to sign in page.
          { location.replace(`/login?from=${props.path}`) }
        </>
      )
}

    // Using router Redirect instead of location.replace
    // <Redirect
    //   from={props.path}
    //   to={{pathname: routes.SIGN_IN, state: {from: props.path}}}
    // />

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

@ hego64 คุณได้ออกจากระบบแอพ firebase แล้วหรือยัง? โซลูชันนี้ไม่ได้ทำการเข้าสู่ระบบอนุญาตให้ข้ามแบบฟอร์มการลงชื่อเข้าใช้หากผู้ใช้ไม่ได้ออกจากระบบในเซสชันก่อน / แก้ไข: คุณอยู่ในลูปการเปลี่ยนเส้นทางหรือไม่? ฉันจะอัปเดตคำตอบ
Qwerty

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

1
@ hego64 ผู้ใช้ที่ไม่ได้ลงชื่อเข้าใช้ไม่ควรเดินไปมาได้อย่างอิสระโดยไม่ต้องใช้วิธีใด ๆ ดังนั้นการเปลี่ยนเส้นทางไปยังหน้าการเข้าสู่ระบบจึงถูกต้อง แต่หากมีเส้นทางที่พร้อมใช้งานโดยไม่มีการตรวจสอบสิทธิ์คุณจะต้องย้ายตรรกะไปที่เราเตอร์ หรือบางเส้นทางแทนเหมือนในตัวอย่าง PrivateRoute wrapper ของฉัน ดังนั้นหากผู้ใช้อยู่ในหน้าที่ถูก จำกัด และออกจากระบบระบบจะเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบ เส้นทางอื่น ๆ ของคุณจะไม่มีการใช้ตรรกะนี้
Qwerty

ฉันติดอยู่เล็กน้อย ... วิธีนี้ได้ผลดี ขอขอบคุณ.
spetz83

21

ไม่จำเป็นต้องใช้ฟังก์ชัน onAuthStateChanged () ในสถานการณ์นี้

คุณสามารถตรวจสอบได้อย่างง่ายดายว่าผู้ใช้เข้าสู่ระบบหรือไม่โดยดำเนินการ:

var user = firebase.auth().currentUser;

สำหรับผู้ที่ประสบปัญหา "คืนค่าว่าง" นั่นเป็นเพียงเพราะคุณไม่ได้รอให้การเรียกใช้ firebase เสร็จสิ้น

สมมติว่าคุณดำเนินการเข้าสู่ระบบในหน้า A จากนั้นคุณเรียกใช้เพจ B ในหน้า B คุณสามารถเรียกรหัส JS ต่อไปนี้เพื่อทดสอบพฤติกรรมที่คาดหวัง:

  var config = {
    apiKey: "....",
    authDomain: "...",
    databaseURL: "...",
    projectId: "..",
    storageBucket: "..",
    messagingSenderId: ".."
  };
  firebase.initializeApp(config);

    $( document ).ready(function() {
        console.log( "testing.." );
        var user = firebase.auth().currentUser;
        console.log(user);
    });

หากล็อกผู้ใช้แล้ว "ผู้ใช้ var" จะมีเพย์โหลด JSON ที่คาดไว้หากไม่เป็นเช่นนั้นจะเป็นเพียง "null"

และนั่นคือทั้งหมดที่คุณต้องการ

ความนับถือ


3
@Mauricio Silvestre คืออะไร? การใช้firebase.auth.currentUserผลตอบแทนที่ไม่ได้กำหนดว่าฉันลงชื่อเข้าใช้อยู่หรือไม่เฉพาะ auth () ส่งคืนผลลัพธ์ที่ถูกต้องเมื่อลงชื่อเข้าใช้
จอร์แดน

6

อีกวิธีหนึ่งคือใช้สิ่งเดียวกับที่ firebase ใช้

ตัวอย่างเช่นเมื่อผู้ใช้เข้าสู่ระบบ firebase จะจัดเก็บรายละเอียดด้านล่างในที่จัดเก็บในตัวเครื่อง เมื่อผู้ใช้กลับมาที่เพจ firebase จะใช้วิธีเดียวกันนี้เพื่อระบุว่าผู้ใช้ควรเข้าสู่ระบบโดยอัตโนมัติหรือไม่

ป้อนคำอธิบายภาพที่นี่

ATTN: เนื่องจาก firebase ไม่ได้อยู่ในรายการหรือแนะนำ คุณสามารถเรียกวิธีนี้ว่าเป็นวิธีที่ไม่เป็นทางการในการทำเช่นนี้ ซึ่งหมายความว่าในภายหลังหาก firebase เปลี่ยนการทำงานภายในวิธีนี้อาจไม่ได้ผล หรือเรียกสั้น ๆ . ใช้ความเสี่ยงของคุณเอง! :)


5

ใช้งานได้:

async function IsLoggedIn(): Promise<boolean> {
  try {
    await new Promise((resolve, reject) =>
      app.auth().onAuthStateChanged(
        user => {
          if (user) {
            // User is signed in.
            resolve(user)
          } else {
            // No user is signed in.
            reject('no user logged in')
          }
        },
        // Prevent console error
        error => reject(error)
      )
    )
    return true
  } catch (error) {
    return false
  }
}

2

หากคุณกำลังช่วยให้ผู้ใช้ที่ไม่ระบุชื่อเช่นเดียวกับผู้เข้าสู่ระบบด้วยอีเมลที่คุณสามารถใช้firebase.auth().currentUser.isAnonymousซึ่งจะกลับมาอย่างใดอย่างหนึ่งหรือtruefalse



-5

ก่อนอื่นให้นำเข้าสิ่งต่อไปนี้

import Firebase
import FirebaseAuth

แล้ว

    // Check if logged in
    if (Auth.auth().currentUser != null) {
      // User is logged in   
    }else{
      // User is not logged in
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.