Срок действия токена Firebase истек и ошибка 401 не авторизована при вызове API ASP.NETC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Срок действия токена Firebase истек и ошибка 401 не авторизована при вызове API ASP.NET

Сообщение Anonymous »

Я работаю над проектом с интерфейсом React, использующим аутентификацию Firebase и серверный API C#. Интерфейс получает и отправляет токен идентификатора Firebase для аутентификации, но я сталкиваюсь с несанкционированной ошибкой 401 с сообщением «Срок действия токена идентификатора Firebase истек» в аутентифицированном запросе.
Код интерфейса (AuthContext) .js):
  • функция makeAuthenticatedRequest обрабатывает аутентифицированные вызовы API и
    пытается обновить токен в случае сбоя.
    < li>getFreshToken управляет обновлением токена с ограничением в 5 минут

Код: Выделить всё

 // AuthContext.js
const getFreshToken = async (force = false) => {
if (!user) return null;

const now = Date.now();
if (force || now - lastTokenRefresh > 5 * 60 * 1000) {
try {
const token = await user.getIdToken(true);
setLastTokenRefresh(now);
return token;
} catch (error) {
console.error('Error refreshing token:', error);
return null;
}
}

return user.getIdToken();
};

const makeAuthenticatedRequest = async (url, options = {}, retryCount = 0) => {
if (!user) {
throw new Error('User not authenticated');
}

try {
const token = await getFreshToken(retryCount > 0);
if (!token) throw new Error('Failed to get authentication token');

const response = await fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});

if (!response.ok) {
const errorData = await response.json();

if (errorData.message?.includes('expired') && retryCount < 2) {
await new Promise(resolve => setTimeout(resolve, 1000));
return makeAuthenticatedRequest(url, options, retryCount + 1);
}

throw new Error(JSON.stringify(errorData));
}

return await response.json();
} catch (error) {
console.error('API request failed:', error);
throw error;
}
};

useEffect(() => {
const checkUserRole = async () => {
if (user) {
try {
const response = await makeAuthenticatedRequest('http://localhost:5067/api/auth/protected');
setIsAdmin(response.user.isAdmin);
} catch (error) {
console.error('Error checking user role:', error);
setIsAdmin(false);
}
} else {
setIsAdmin(false);
}
};

checkUserRole();
}, [user]);

useEffect(() => {
if (!user) return;

const refreshInterval = setInterval(async () => {
await getFreshToken(true);
}, 10 * 60 * 1000);

return () => clearInterval(refreshInterval);
}, [user]);

Верхний код (AuthController.cs): конечная точка TestProtected проверяет токен и разрешения пользователя.

Код: Выделить всё

// AuthController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using FirebaseAdmin.Auth;
using UniLostAndFound.API.Services;
using UniLostAndFound.API.Models;

namespace UniLostAndFound.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly ILogger _logger;
private readonly FirestoreService _firestoreService;

public AuthController(ILogger logger, FirestoreService firestoreService)
{
_logger = logger;
_firestoreService = firestoreService;
}

[HttpGet("test")]
public ActionResult TestPublic()
{
return Ok(new { message = "Public endpoint working!" });
}

[HttpGet("protected")]
public async Task TestProtected()
{
try
{
string authHeader = Request.Headers["Authorization"].ToString();
_logger.LogInformation($"Auth Header received: {authHeader.Length} characters");

if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer "))
{
return Unauthorized(new { message = "No Bearer token found"  });
}

string idToken = authHeader.Substring("Bearer ".Length);

try
{
var firebaseToken = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
string email = firebaseToken.Claims.GetValueOrDefault("email", "").ToString();
string name = firebaseToken.Claims.GetValueOrDefault("name", "").ToString();

// Check if email is allowed
if (!await _firestoreService.IsAllowedEmail(email))
{
return Unauthorized(new { message = "Email domain not allowed" });
}

// Check if user is admin
bool isAdmin = await _firestoreService.IsAdminEmail(email);

return Ok(new
{
message = "Authentication successful",
user = new
{
uid = firebaseToken.Uid,
email = email,
name = name,
isAdmin = isAdmin
}
});
}
catch (FirebaseAuthException ex)
{
_logger.LogWarning($"Token verification failed: {ex.Message}");
return Unauthorized(new { message = ex.Message });
}
catch (Exception ex)
{
_logger.LogError($"Unexpected error during token verification: {ex.Message}");
return StatusCode(500, new { message = "Internal server error during authentication" });
}
}
catch (Exception ex)
{
_logger.LogError($"Unexpected error: {ex.Message}");
return StatusCode(500, new { message = "Internal server error" });
}
}
}
Program.cs

Код: Выделить всё

// Update the JWT Bearer configuration
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
var projectId = "unilostandfound";
options.Authority = $"https://securetoken.google.com/{projectId}";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = $"https://securetoken.google.com/{projectId}",
ValidateAudience = true,
ValidAudience = projectId,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(5)
};
});
Возникшие проблемы
  • 401 Несанкционировано: при выполнении аутентифицированных запросов из
    интерфейса я часто получаю сообщение Ошибка 401.
  • Срок действия токена: сообщение об ошибке указывает на то, что срок действия токена Firebase ID
    истек. Я думал, что функция getFreshToken() в моем
    AuthContext.js справится с обновлением, но, похоже,
    иногда она дает сбой.
Что я пробовал
  • Реализовать механизм обновления токена, который пытается получить новый ID
    токен, если срок действия текущего истек.
    Повторная попытка запроса API один раз, если обнаружена ошибка 401.
Честно говоря, я сейчас очень растерян и не могу точно определить, что является причиной истечения срока действия токена. Почему токены так быстро истекают? Я неправильно обработал токен, если да, то какое решение лучше всего? Наконец, пропустил ли я что-нибудь из своего бэкэнда? Спасибо.

Подробнее здесь: https://stackoverflow.com/questions/791 ... t-api-call
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Функция шлюза Google Cloud API 401 не авторизована
    Гость » » в форуме Python
    0 Ответы
    21 Просмотры
    Последнее сообщение Гость
  • Как проверить, истек ли срок действия токена JWT без исключений?
    Гость » » в форуме JAVA
    0 Ответы
    85 Просмотры
    Последнее сообщение Гость
  • 419 Срок действия страницы истек в Laravel даже после добавления токена CSRF
    Anonymous » » в форуме Php
    0 Ответы
    174 Просмотры
    Последнее сообщение Anonymous
  • Есть ли способ проверить, истек ли срок действия токена oauth или нет?
    Anonymous » » в форуме C#
    0 Ответы
    61 Просмотры
    Последнее сообщение Anonymous
  • Pyotp показывает ошибку otp с истекшим сроком действия, даже если срок ее действия еще не истек
    Anonymous » » в форуме Python
    0 Ответы
    44 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»