Заметки ASP.NET Web API/Backend разработчика (часть 1)
В сегодняшней небольшой заметке хотел бы поделиться некоторыми вещами, с которыми столкнулся за последнее время и о которых бы не хотелось забыть.
Бесконечный refresh token в oauth 2 (Microsoft.Owin)
При реализации авторизации с использованием oauth 2 Refresh token используется для обновления выданного ранее access token. Срок жизни (expiration time) refresh token’a обычно больше срока жизни access token’a, однако, мне захотелось сделать его бесконечным (по аналогии с OAuth 2.0 to access google APIs) (его срок протухания наступает в тот момент, когда его отзовут вручную).
Однако в реализации Microsoft этого сделать нельзя ввиду следующего условия при валидации токена.
По умолчанию срок его жизни устанавливается таким же, как и срок жизни access token’a, однако, есть возможность его изменить (сделать больше или меньше). В случае же присваивания ему значения null, сам токен станет невалидным (попытка продлить им access token будет безуспешной).
В итоге я остановился на варианте 1 месяц для access и 1 год для refresh.
Заглушка для IIS приложений
Время от времени бывает необходимо все запросы к ASP.NET приложениям, которые хостятся с использованием IIS, перенаправлять на некую статическую страницу, например:
- На сайте ведутся работы;
- В данный момент сайт недоступен, попробуйте позже;
- Страница недоступности сайта (для симуляции экстренного выключения).
Самым простым и автоматизируемым решением, на мой взгляд, является размещение файла с именем app_offline.htm в корне приложения. В этом случае произойдёт следующее:
- Приложение будет завершено;
- Все занимаемые приложением ресурсы будут освобождены;
- Все новые входящие запросы не будут обработаны;
Главное не забудьте удалить этот файл!
NHibernate и nvarchar(max)
К сожалению (или к счастью) NHibernate по умолчанию не умеет работать с некоторыми типами MS SQL (будь-то datetime2 или nvarchar(max)). В этом случае придётся на соответствующем поле вызвать CustomType
и CustomSqlType
, где явно указать, какому типу в базе данных соответствует данное поле:
Map(x => x.Description).CustomType("StringClob").CustomSqlType("nvarchar(max)");
SCOPE_IDENTITY() for Guids (uniqueidentifier)
В том случае, когда вы используете Guid’ы (mssql- uniqueidentifier) и вам требуется соблюдение их уникальности (например, в случае с primary key), вам потребуется функция, которая будет формировать уникальные ключи (SCOPE_IDENTITY()). Есть 2 варианта это сделать:
Генерация на стороне mssql
Для этого используем встроенную функцию newsequentialid()
:
CREATE TABLE dbo.GuidTest (
GuidColumn uniqueidentifier NOT NULL DEFAULT NewSequentialID(),
IntColumn int NOT NULL
)
Генерация на стороне ORM
В случае с NHibernate эту функцию можно задать с использованием маппинга Id
:
Id(p => p.Id).GeneratedBy.GuidComb();
Вариант с использованием GuidComb()
является более приоритетным ввиду повышения производительности базы данных при вставках новых записей вследствие уменьшения фрагментации индексов, т.к. элементы последовательности получаются близкими по значению.
В случае с Entity Framework:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
Используемые материалы: