96 lines
3.1 KiB
Markdown
96 lines
3.1 KiB
Markdown
`API/users.ts`
|
||
```ts
|
||
|
||
export async function login(data: TokenObtainPair): Promise<JwtTokenResponse | null>
|
||
|
||
export async function refreshToken(data: TokenRefresh): Promise<JwtTokenResponse | null>
|
||
|
||
export async function verifyToken(data: TokenVerify): Promise<boolean>
|
||
```
|
||
|
||
`utils/users/UserProvider.tsx`
|
||
```tsx
|
||
export function UserProvider({ children }: { children: ReactNode }) {
|
||
const [user, setUser] = useState<Account | undefined>(() => {
|
||
const storedUser = localStorage.getItem('user');
|
||
return storedUser ? JSON.parse(storedUser) : undefined;
|
||
});
|
||
const [tokens, setTokens] = useState<JwtTokenResponse | undefined>(() => {
|
||
const storedTokens = localStorage.getItem('tokens');
|
||
return storedTokens ? JSON.parse(storedTokens) : undefined;
|
||
});
|
||
|
||
useEffect(() => {
|
||
if (tokens?.access) {
|
||
localStorage.setItem('tokens', JSON.stringify(tokens));
|
||
} else {
|
||
localStorage.removeItem('tokens');
|
||
}
|
||
}, [tokens]);
|
||
|
||
useEffect(() => {
|
||
if (user) {
|
||
localStorage.setItem('user', JSON.stringify(user));
|
||
} else {
|
||
localStorage.removeItem('user');
|
||
}
|
||
}, [user]);
|
||
|
||
const handleLogin = async (credentials: TokenObtainPair) => {
|
||
const tokens = await apiLogin(credentials);
|
||
if (tokens) {
|
||
setTokens(tokens);
|
||
// Здесь можно добавить запрос для получения данных пользователя
|
||
setUser({ id: 1, login: credentials.login, is_staff: false, is_active: true } as Account); // TODO
|
||
}
|
||
};
|
||
|
||
const handleLogout = () => {
|
||
setUser(undefined);
|
||
setTokens(undefined);
|
||
};
|
||
|
||
const validateToken = async () => {
|
||
if (tokens?.access) {
|
||
const isValid = await verifyToken({ token: tokens.access });
|
||
if (!isValid && tokens.refresh) {
|
||
const newTokens = await refreshToken({ refresh: tokens.refresh });
|
||
if (newTokens) {
|
||
setTokens(newTokens);
|
||
} else {
|
||
handleLogout();
|
||
}
|
||
} else if (!isValid) {
|
||
handleLogout();
|
||
}
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
validateToken().then();
|
||
}, []);
|
||
|
||
return (
|
||
<UserContext.Provider value={{ user, login: handleLogin, logout: handleLogout }}>
|
||
{children}
|
||
</UserContext.Provider>
|
||
);
|
||
}
|
||
```
|
||
|
||
|
||
В частности обрати внимание на эту функцию
|
||
```ts
|
||
const handleLogin = async (credentials: TokenObtainPair) => {
|
||
const tokens = await apiLogin(credentials);
|
||
if (tokens) {
|
||
setTokens(tokens);
|
||
// Здесь можно добавить запрос для получения данных пользователя
|
||
setUser({ id: 1, login: credentials.login, is_staff: false, is_active: true } as Account); // TODO
|
||
}
|
||
};
|
||
```
|
||
|
||
Воспользуйся эндпоинтами /users/auth/users/me/ для получения id текущего пользователя
|
||
|