哪个钩子更适合用于授权验证?

huangapple go评论168阅读模式
英文:

Which hook is more suitable for authorization verification?

问题

我在思考从逻辑角度来看,哪种方法会是最正确的。我想检查渲染组件的授权,但现在 useEffect 只在页面首次渲染或重新启动时起作用,因为它有一个依赖项 [ ]。哪种实现方式会是最简洁的,更重要的是从 hooks 的角度来看,以便用户在授权后获取组件而无需重新启动。

我有一个名为 auth 的函数:

import { useEffect, useState } from "react"

export function useCheckCookieToken() {
  const [session, setSession] = useState()
  const [loading, setLoading] = useState(true)
  const [name, setName] = useState('')
  const [role, setRole] = useState('')

  useEffect(() => {
    let cancel = false
    async function sessionPost() {
      const res = await fetch(`/api/checkCookie`, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json'
        },
      })
      if (res.ok) {
        const result = await res.json()
        if (!cancel) {
          setSession(result)
          setName(result.user.name)
          setRole(result.user.role)
          setLoading(false)
        }
      } else {
        setLoading(false)
      }
    }
    sessionPost()
    return () => {
      cancel = true
    }
  }, [])

  return { session, loading, role, name }
}

我的组件:

const [authenticated, setAuthenticated] = useState(false)

const { session, loading, name } = useCheckCookieToken()

useEffect(() => {
  if (session) {
    setNameUser(name)
    setAuthenticated(true)
  } else {
    setAuthenticated(false)
  }
}, [session])

return (
  <>
    {
      loading ? (
        <div><CircularProgress/></div>
      ) : session ? (
        <>
          <Auth />
        </>
      ) : (
        <>
          <NotAuth />
        </>
      )
    }
  </>
)

添加 useContext 后

现在我添加了带有 useContext 的 authProvider.js

import { createContext, useContext, useState } from 'react';

const AuthContext = createContext();

export function useAuth() {
    return useContext(AuthContext);
}

export function AuthProvider({ children }) {
    const [authenticated, setAuthenticated] = useState(false);
    const [session, setSession] = useState(null)
    const [loading, setLoading] = useState(true)
    const [name, setName] = useState('')
    const [role, setRole] = useState('')

    const login = async () => {
        try {
            const res = await fetch(`/api/checkCookie`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json'
                },
            });
            if (res.ok) {
                const result = await res.json();
                setSession(result);
                setName(result.user.name);
                setRole(result.user.role);
                setLoading(false);
                setAuthenticated(true);
            } else {
                setLoading(false);
                setAuthenticated(false);
            }
        } catch (error) {
            console.error(error);
            setLoading(false);
            setAuthenticated(false);
        }
    };

    const logout = async () => {
        try {
            const res = await fetch('/api/logout', {
                method: 'GET',
                headers: {
                    'Authorization': 'bearer ' + localStorage.getItem('sid'),
                    'Content-Type': 'application/json'
                }
            });
            if (res.ok) {
                setAuthenticated(false);
                console.log("成功退出登录");
            } else {
                console.error("退出登录失败");
            }
        } catch (error) {
            console.error(error);
        }
    };


    const authContextValue = {
        authenticated,
        login,
        logout,
    };

    return (
        <AuthContext.Provider value={authContextValue}>{children}</AuthContext.Provider>
    );
}   

但我遇到了一个错误:

无法解构属性 'authenticated' of '(0 , _services_authProvider__WEBPACK_IMPORTED_MODULE_14__.useAuth)(...)',因为它是未定义的。
TypeError: Cannot destructure property 'authenticated' of '(0 , _services_authProvider__WEBPACK_IMPORTED_MODULE_14__.useAuth)(...)' as it is undefined.

使用 useContext 更新后的组件:

function MainPage() {
  const { authenticated, login, logout } = useAuth();

 useEffect(() => {
    if (authenticated) {
      setNameUser(name);
    } else {
      setNameUser('');
    }
  }, [authenticated]);

return (
    <>
      <AuthProvider.Provider value={{name}}>
        {
          loading ? (
            <div><CircularProgress /></div> 
          ) : session ? (
            <>
            <h1>{name}</h1>
             
            </>
          ) : (
            <>
              <Bar/>
            </>
          )
        }
      </AuthProvider.Provider>
    </>
  )
}
英文:

I'm wondering how the method will be the most correct from the point of view of logic. I want to check authorization for rendering components , but now useEffect only works there when the page is first rendered or restarted , because it has a dependency [ ] . Which implementation will be the most loconic, and most importantly correct from the point of view of hooks, so that the user receives components after authorization without restarting.

I have function auth :

 import { useEffect, useState } from &quot;react&quot;

export function useCheckCookieToken() {
  const [session, setSession] = useState()
  const [loading, setLoading] = useState(true)
  const [name,setName]=useState(&#39;&#39;)
  const [role,setRole]=useState(&#39;&#39;)

  useEffect(() =&gt; {
    let cancel = false
    async function sessionPost() {
      const res = await fetch(`/api/checkCookie`, {
        method: &#39;GET&#39;,
        headers: {
          &#39;Content-Type&#39;: &#39;application/json&#39;
        },
      })
      if (res.ok) {
        const result = await res.json()
        if (!cancel) {
          setSession(result)
          setName(result.user.name)
          setRole(result.user.role)
          setLoading(false)
        }
      } else {
        setLoading(false)
      }
    }
    sessionPost()
    return () =&gt; {
      cancel = true
    }
  }, [])

  //  console.log(session.user.name)
  return { session, loading , role ,name}
}

My comp:

const [authenticated, setAuthenticated] = useState(false); 

const { session, loading, name } = useCheckCookieToken();

  useEffect(() =&gt; {
    if (session) {
      setNameUser(name);
      setAuthenticated(true);
    } else {
      setAuthenticated(false);
    }
  }, [session]);

  return (
    &lt;&gt;
      {
        loading ? (
          &lt;div&gt;&lt;CircularProgress/&gt;&lt;/div&gt; 
        ) : session ? (
          &lt;&gt;
            &lt;Auth /&gt;
            /&gt;
          &lt;/&gt;
        ) : (
          &lt;&gt;
           &lt;NotAuth /&gt;
          &lt;/&gt;
        )
      }
    &lt;/&gt;
  )

> AFTER ADD useContext

Now i add authProvider.js with useContext :

import { createContext, useContext, useState } from &#39;react&#39;;

const AuthContext = createContext();


export function useAuth() {
    return useContext(AuthContext);
}

export function AuthProvider({ children }) {
    const [authenticated, setAuthenticated] = useState(false);
    const [session, setSession] = useState(null)
    const [loading, setLoading] = useState(true)
    const [name, setName] = useState(&#39;&#39;)
    const [role, setRole] = useState(&#39;&#39;)

    const login = async () =&gt; {
        try {
            const res = await fetch(`/api/checkCookie`, {
                method: &#39;GET&#39;,
                headers: {
                    &#39;Content-Type&#39;: &#39;application/json&#39;
                },
            });
            if (res.ok) {
                const result = await res.json();
                setSession(result);
                setName(result.user.name);
                setRole(result.user.role);
                setLoading(false);
                setAuthenticated(true);
            } else {
                setLoading(false);
                setAuthenticated(false);
            }
        } catch (error) {
            console.error(error);
            setLoading(false);
            setAuthenticated(false);
        }
    };

    const logout = async () =&gt; {
        try {
            const res = await fetch(&#39;/api/logout&#39;, {
                method: &#39;GET&#39;,
                headers: {
                    &#39;Authorization&#39;: &#39;bearer &#39; + localStorage.getItem(&#39;sid&#39;),
                    &#39;Content-Type&#39;: &#39;application/json&#39;
                }
            });
            if (res.ok) {
                setAuthenticated(false);
                console.log(&quot;Success logout&quot;);
            } else {
                console.error(&quot;Failed to logout&quot;);
            }
        } catch (error) {
            console.error(error);
        }
    };


    const authContextValue = {
        authenticated,
        login,
        logout,
    };

    return (
        &lt;AuthContext.Provider value={authContextValue}&gt;{children}&lt;/AuthContext.Provider&gt;
    );
}   

And i have error :

Cannot destructure property &#39;authenticated&#39; of &#39;(0 , _services_authProvider__WEBPACK_IMPORTED_MODULE_14__.useAuth)(...)&#39; as it is undefined.
TypeError: Cannot destructure property &#39;authenticated&#39; of &#39;(0 , _services_authProvider__WEBPACK_IMPORTED_MODULE_14__.useAuth)(...)&#39; as it is undefined.

Updating comp after useContext:

function MainPage() {
  const { authenticated, login, logout } = useAuth();

 useEffect(() =&gt; {
    if (authenticated) {
      setNameUser(name);
    } else {
      setNameUser(&#39;&#39;);
    }
  }, [authenticated]);

return (
    &lt;&gt;
      &lt;AuthProvider.Provider value={{name}}&gt;
        {
          loading ? (
            &lt;div&gt;&lt;CircularProgress /&gt;&lt;/div&gt; 
          ) : session ? (
            &lt;&gt;
            &lt;h1&gt;{name}&lt;/h1&gt;
             
            &lt;/&gt;
          ) : (
            &lt;&gt;
              &lt;Bar/&gt;
            &lt;/&gt;
          )
        }
      &lt;/AuthProvider.Provider&gt;
    &lt;/&gt;
  )
}

答案1

得分: 1

最好的方法是使用useContext Hook。您需要全局访问用户状态。

您可以查看如何实现这一点的链接:
点击此处查看链接描述

英文:

the best way is to use useContext Hook. u need to access the users state globally.

you can see how to implement this from link below:
enter link description here

huangapple
  • 本文由 发表于 2023年6月1日 15:26:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379568.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定