Wie kann ich meine Next-Auth-Benutzersitzung aufrechterhalten und die Daten mithilfe der bereitgestellten ID auf anderen Routen abrufen?
P粉744691205
P粉744691205 2023-08-25 15:35:57
0
2
503
<p>Was ich hier erreichen möchte, ist, dass ich bei jeder Anmeldung eines Benutzers die zurückgegebenen Daten speichern möchte, da die Daten eine ID enthalten, die ich in anderen Routen zum Abrufen der Daten verwenden werde. Wenn sich der Benutzer erfolgreich anmeldet, wird er zur Route /home weitergeleitet und die aus der Sitzung erhaltene ID wird zum Abrufen der Daten verwendet. Alles funktioniert einwandfrei, aber wenn ich die Startseite aktualisiere, wird der Benutzer leer. </p> <p>So sieht meine [...nextauth].js-Datei aus.</p> <pre class="brush:php;toolbar:false;">NextAuth aus "next-auth" importieren; CredentialsProvider aus „next-auth/providers/credentials“ importieren; Axios aus „Axios“ importieren; Standard-NextAuth({ exportieren) Anbieter: [ CredentialsProvider({ Name: "Anmeldeinformationen", Referenzen: { Benutzername: { Label: "Benutzername", Typ: "Text", Platzhalter: "justin" }, Passwort: {Label: "Passwort", Typ: "Passwort", Platzhalter: "******"}, }, asynchrone Autorisierung (Anmeldeinformationen, erforderlich) { const url = req.body.callbackUrl.split("/auth")[0]; const { Benutzername, Passwort } = Anmeldeinformationen; const user = wait axios({ URL: „${url}/api/user/login“, Methode: "POST", Daten: { Benutzername: Benutzername, Passwort: Passwort, }, "content-type": "application/json", }) .then((res) => { return res.data; }) .catch((err) => { if (err.response.data) { throw new Error(err.response.data); } anders { null zurückgeben; } null zurückgeben; }); Benutzer zurückgeben; }, }), ], Rückrufe: { jwt: ({ token, user }) => { if (Benutzer) { token.user = Benutzer; } Rückgabe-Token; }, Sitzung: ({ Sitzung, Token }) => { if (Token) { session.user = token.user; } Rückfahrt; }, }, Seiten: { signIn: "/auth/login", neuerBenutzer: "/auth/register", }, });</pre> <p>这是我的/home路由的样子</p> <pre class="brush:php;toolbar:false;">Karte importieren aus "@/components/card/Card"; import React, { useEffect, useState } aus "react"; Stile aus „./home.module.css“ importieren; import { Ubuntu } from "@next/font/google"; import { useSession } from "next-auth/react"; import { useDispatch, useSelector } aus „react-redux“; const ubuntu = Ubuntu({ Gewicht: "500", Teilmengen: ["kyrillisch"] }); const getData = async (id) => { const res = warte auf fetch({ URL: "http://localhost:3000/api/note/getall", Methode: "POST", "content-type": "application/json", Daten: { Ich tat, }, }); if (!res.ok) { console.log(id); throw new Error("Abruf nicht möglich"); } anders { return res.json(); console.log(res); } }; Funktion home() { const Colors = ["#E9F5FC", "#FFF5E1", "#FFE9F3", "#F3F5F7"]; const random = Math.floor(Math.random() * 5); const rc = farben[zufällig]; const [pop, setPop] = useState("none"); const { user } = useSelector((state) => state.user); const getDataa = async () => { console.log(Benutzer) const data = waiting getData(user._id); console.log(data); }; useEffect(() => { if (Benutzer) { Warnung(Benutzer) } }, []); zurückkehren ( <div className={styles.home}> <Kopfzeile> <h3 className={ubuntu.className}> Hallo, <br /> {Benutzer?.Benutzername}! </h3> <Eingabetyp="Text" placeholder="suchen" /> </header> <div className={styles.nav}> <h1 className={ubuntu.className}>Notizen</h1> </div> <div className={styles.section}> <div className={styles.inner}> {/* {Daten && data.map((e) => ( <Karte rawData={e} color={colors[Math.floor(Math.random() * farben.length)]} /> ))} */} </div> </div> <div className="new"></div> </div> ); } Standard-Home exportieren;</pre></p>
P粉744691205
P粉744691205

Antworte allen(2)
P粉428986744

这段代码似乎会创建一个问题/竞争条件,因为你混合了两种不同的异步Promise处理方式:

const user = await axios({
  url: `${url}/api/user/login`,
  method: "POST",
  data: {
    username: username,
    password: password,
  },
  "content-type": "application/json",
})
  .then((res) => {
    return res.data;
  })
  .catch((err) => {
    if (err.response.data) {
      throw new Error(err.response.data);
    } else {
      return null;
    }
    return null;
  });
return user;

应该改成这样:

try {
  const user = await axios({
    url: `${url}/api/user/login`,
    method: "POST",
    data: {
      username: username,
      password: password,
    },
    "content-type": "application/json",
  });
  return user.data;
} catch (err) {
  if (err.response.data) {
    throw new Error(err.response.data);
  } else {
    return null;
  }
}

或者这样:

axios({
  url: `${url}/api/user/login`,
  method: "POST",
  data: {
    username: username,
    password: password,
  },
  "content-type": "application/json",
}).then((res) => {
  return res.data;
}).catch((err) => {
  if (err.response.data) {
    throw new Error(err.response.data);
  } else {
    return null;
  }
  return null;
});
P粉707235568

将此component添加到您的App.js文件中:

function Auth({ children }) {
  const router = useRouter();
  const { status } = useSession({
    required: true,
    onUnauthenticated() {
      router.push("/sign-in");
    },
  });

  if (status === "loading") {
    return 
Loading ...
; } return children; }

现在在您的App函数中,不再返回<Component {...pageProps} />,而是首先检查component是否具有auth属性,所以您将其包装在<Auth>中,以确保每个需要会话的组件只有在会话加载完成后才会挂载(这就是为什么用户为null,因为会话仍在加载中)

{
  Component.auth ? (
    
      
    
  ) : (
    
  );
}

最后,您将.auth = {}添加到您想要定义会话的每个页面中(在您的情况下是Home)

const Home = () => {
//....
}
Home.auth = {};

这还有助于在会话过期时将用户重定向到/sign-in页面

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage