简体   繁体   English

如何在 ReactJS 上使用 JWT 令牌注销

[英]How logout using JWT token on ReactJS

I am using an API in nodeJS and APP in ReactJS.我在 nodeJS 中使用 API,在 ReactJS 中使用 APP。 On nodeJS I'm doing the JWT token validation.在 nodeJS 上,我正在进行 JWT 令牌验证。 In reactJS I use to check if it's valid, otherwise I ask to authenticate again.在 reactJS 中,我用来检查它是否有效,否则我要求再次进行身份验证。 Now I save JWT token in localStorage, if you have something safer let me know.现在我将 JWT 令牌保存在 localStorage 中,如果您有更安全的东西,请告诉我。

My problems:我的问题:

  1. Send a request to the API and wait for the response is too slow (2 seconds).向 API 发送请求并等待响应太慢(2 秒)。
  2. When the time of the token and page change expired, it goes to login and when logging in, it locks on the same page (login), only reloading the page to work.当令牌和页面更改的时间到期时,它会登录,登录时,它会锁定在同一页面(登录),仅重新加载页面才能工作。
  3. When the token is invalid and I change the page, the page is completely blank.当令牌无效并且我更改页面时,页面完全空白。

Problem 1: Could I validate the token in the APP instead of requesting it all the time to the API, would this be the most correct solution?问题 1:我可以在 APP 中验证令牌,而不是一直向 API 请求它,这是最正确的解决方案吗? Problem 2 and 3: I believe it's the problem in logic where validation takes place after page rendering.问题 2 和 3:我认为这是在页面渲染后进行验证的逻辑问题。

My APP Code:我的APP代码:

App.tsx应用程序.tsx

import AdminPrivateRoute from './AdminPrivateRoute';
import { AuthContextProvider } from './contexts/AuthContext';

export default function App() {
    return (
        <BrowserRouter>
            <AuthContextProvider>
                <Switch>
                    <Route path="/" exact component={Home} />
                    <AdminPrivateRoute path="/admin" component={Admin} />
                    <Route path="*" component={() => <h1>Page not found 404</h1>} />
                </Switch>
            </AuthContextProvider>
        </BrowserRouter>
    );
}

AdminPrivateRoute.tsx AdminPrivateRoute.tsx

import { getToken, logout } from './Auth';
import Api from './Api';

const AdminPrivateRoute = ({component: Component, ...rest}) => {
    useEffect(() => {
        // Here I make a fetch call to validate the token in the API
        Api.checkToken(getToken() || '').then(res => {
            if (!res.auth) {
                logout();
            }
        });
    })

    return (
        <Route
            {...rest}
            render={props =>
                isAuthenticated() ? (
                    <Component {...props} />
                ) : (
                    <SignIn />
                )
            }
        />
    );
};

Auth.ts身份验证

export const TOKEN_KEY = 'XYZ';
export const getToken = () => localStorage.getItem(TOKEN_KEY);
export const isAuthenticated = () => getToken() !== null; // I thought about validating the token right here in the app
export const setToken = (token: string) => {
    localStorage.setItem(TOKEN_KEY, token);
};
export const logout = () => {
    localStorage.removeItem(TOKEN_KEY);
};

AuthContextProvider.tsx (I removed all declare types) AuthContextProvider.tsx(我删除了所有声明类型)

import Api from './Api';
import { setToken } from './Auth';

export function AuthContextProvider(props) {
    const [user, setUser] = useState();

    async function signIn({email, password}) {
        // TODO: Validations here

        const res = await Api.adminSignIn({email, password});

        if (!res.auth) {
            throw new Error(res.message);
        }

        if (res.token) {
            setToken(res.token);
        }

        const {name} = res.user;

        setUser({
            name,
        });
    }

    return (
        <AuthContext.Provider value={{user, signIn}}>
            {props.children}
        </AuthContext.Provider>
    );
}

Thanks in advance.提前致谢。

so here is the solution of your problems所以这是您问题的解决方案

Problem-1问题 1

Send a request to the API and wait for the response is too slow (2 seconds).

Solution解决方案

make a state in your component by name loading which is by default false just before api call change it to true .通过名称loading在您的组件中创建一个状态,在 api 调用之前默认为false将其更改为true on login/signIn button show spinner if loading state is true.如果加载状态为真,则在登录/登录按钮上显示微调器。 When you recieve the response of API make loading to false and if token is authenticated and valid save it in cookies [because cookies are safer then localstorage]当您收到 API 的响应时,将加载为 false,如果令牌经过身份验证且有效,则将其保存在 cookie 中 [因为 cookie 比本地存储更安全]

Problem-2问题 2

When the time of the token and page change expired, it goes to login and when logging in, it locks on the same page (login), only reloading the page to work.

Solution解决方案

This is because when your store in localStorage, as i think on reloading you lose your JWT token for this i recommand you to use Reducer and also its persist form.这是因为当您在 localStorage 中存储时,我认为在重新加载时您会丢失 JWT 令牌,因此我建议您使用Reducer及其持久形式。

Problem-3问题 3

When the token is invalid and I change the page, the page is completely blank.

Solution解决方案

When token is Invalid redirect user to login page当令牌无效时,将用户重定向到登录页面

Note:笔记:

send your JWT token in each api call to also authenticate your api's在每个 api 调用中发送您的 JWT 令牌以验证您的 api

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM