Advertisement
djbob2000

Untitled

Aug 19th, 2024
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. В данной конфигурации используется один основной токен - JWT (JSON Web Token). Когда я говорю "Токен генерируется сервером авторизации", это означает следующее:
  2. В системе есть отдельный сервер авторизации (IdentityServer), который отвечает за аутентификацию пользователей и выдачу токенов.
  3. Когда пользователь успешно проходит аутентификацию, IdentityServer создает JWT токен, содержащий информацию о пользователе и его правах.
  4. Этот JWT токен затем используется клиентом (например, веб-приложением) для доступа к защищенным ресурсам API.
  5. API проверяет подлинность этого токена при каждом запросе, используя настройки, указанные в методе AddAuthentication.
  6. Таким образом, основной поток работы с токеном централизован и управляется сервером авторизации, что повышает безопасность и упрощает управление доступом в распределенной системе.
  7.  
  8. Теперь напиши код с учетом этих данных.
  9.  
  10.  
  11.  
  12. Понял вас. Учитывая предоставленную информацию, давайте реализуем подход, аналогичный C# коду, но для нашего TypeScript/Next.js приложения. Вот обновленная версия кода:
  13.  
  14. Создадим файл auth-server.ts для имитации функциональности IdentityServer:
  15. import jwt from 'jsonwebtoken';
  16.  
  17. const JWT_SECRET = process.env.JWT_SECRET!;
  18. const JWT_EXPIRY = '1h';
  19.  
  20. export function generateToken(userId: string, claims: object) {
  21.   return jwt.sign({ sub: userId, ...claims }, JWT_SECRET, { expiresIn: JWT_EXPIRY });
  22. }
  23.  
  24. export function verifyToken(token: string) {
  25.   try {
  26.     return jwt.verify(token, JWT_SECRET);
  27.   } catch {
  28.     return null;
  29.   }
  30. }
  31.  
  32.  
  33.  
  34. Обновим функцию logInLucia в LoginForm.funcs.tsx:
  35. import { generateToken } from './auth-server';
  36.  
  37. export async function logInLucia(userName: string, password: string): Promise<LoginLuciaResult> {
  38.     const existingUser = await getUserByUserName(userName.toLowerCase());
  39.  
  40.     if (!existingUser || !await verify(existingUser.PasswordHash!, password, {...})) {
  41.         return { isSuccess: false, message: "Incorrect username or password" };
  42.     }
  43.  
  44.     const token = generateToken(existingUser.Id, {
  45.         userName: existingUser.UserName,
  46.         // Добавьте другие необходимые claims
  47.     });
  48.  
  49.     return {
  50.         isSuccess: true,
  51.         user: JSON.parse(JSON.stringify(existingUser)) as User,
  52.         token
  53.     };
  54. }
  55.  
  56.  
  57.  
  58. В компоненте LoginForm на клиенте:
  59. const onSubmit: SubmitHandler<Login> = useCallback(
  60.     async (data) => {
  61.         const result = await logInLucia(data.UserName, data.Password);
  62.  
  63.         if (!result.isSuccess) {
  64.             setErrorMessage(result.message);
  65.             return;
  66.         }
  67.  
  68.         localStorage.setItem('token', result.token);
  69.  
  70.         authContext.setLoginState({
  71.             loggedIn: true,
  72.             userId: result.user!.Id,
  73.             displayName: result.user!.UserName,
  74.         });
  75.  
  76.         router.push(`/${routeConstants.list}?${resourceNameApiParam}=${resourceNames.Person}`);
  77.     },
  78.     [router, authContext]
  79. );
  80.  
  81.  
  82.  
  83. Обновим api-client.ts для использования JWT:
  84. import { verifyToken } from './auth-server';
  85.  
  86. @injectable()
  87. export class ApiClient {
  88.     // ... существующий код ...
  89.  
  90.     #getHeaders(headers?: Headers, skipContentType = false) {
  91.         const newHeaders = headers ? headers : new Headers();
  92.         // ... существующий код ...
  93.         const token = localStorage.getItem('token');
  94.         if (token) {
  95.             const decodedToken = verifyToken(token);
  96.             if (decodedToken) {
  97.                 newHeaders.set('Authorization', `Bearer ${token}`);
  98.             } else {
  99.                 // Токен недействителен, нужно перенаправить на страницу входа
  100.                 // Здесь можно использовать глобальное состояние или событие для обработки этой ситуации
  101.             }
  102.         }
  103.         return newHeaders;
  104.     }
  105.  
  106.     // ... остальной код ...
  107. }
  108.  
  109.  
  110.  
  111. Создадим middleware для проверки JWT на сервере (например, в файле auth-middleware.ts):
  112. import { NextApiRequest, NextApiResponse } from 'next';
  113. import { verifyToken } from './auth-server';
  114.  
  115. export function authMiddleware(handler: (req: NextApiRequest, res: NextApiResponse) => Promise<void>) {
  116.     return async (req: NextApiRequest, res: NextApiResponse) => {
  117.         const authHeader = req.headers.authorization;
  118.         if (!authHeader || !authHeader.startsWith('Bearer ')) {
  119.             return res.status(401).json({ message: 'Unauthorized' });
  120.         }
  121.  
  122.         const token = authHeader.split(' ')[1];
  123.         const decodedToken = verifyToken(token);
  124.  
  125.         if (!decodedToken) {
  126.             return res.status(401).json({ message: 'Invalid token' });
  127.         }
  128.  
  129.         // Добавляем информацию о пользователе в запрос
  130.         (req as any).user = decodedToken;
  131.  
  132.         return handler(req, res);
  133.     };
  134. }
  135.  
  136.  
  137.  
  138. Этот код реализует централизованный подход к управлению токенами, аналогичный вашему C# коду с IdentityServer. JWT генерируется на сервере, используется клиентом для аутентификации и проверяется при каждом запросе к API.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement