В цій статті я розкажу про додатки Heroku, ми створимо базу даних PostgreSQL і налаштуємо її для підтримки процесу аутентифікації у веб-програмі ASP.NET Core. Це друга стаття циклу, тому варто ознайомитись з попередньою, в якій проєкт було створено і розгорнуто. Створена база даних не буде вимагати жодних фінансових витрат і гарно підходить для власного невеликого проєкту.
Передумови
Для успішного виконання наступних кроків вам необхідно зареєструвати акаунт в Heroku, якщо ви цього ще не зробили, та встановити такі інструменти:
Вся робота буде відбуватись в командному рядку. У якості редактору коду можна використовувати будь-який на ваш вибір.
У попередній статті ми створили просту програму ASP.NET Core, налаштували її для роботи в Heroku і розгорнули у хмарі. В цій статті ми модифікуємо створений код: додамо аутентифікацію та базу даних для зберігання інформації про користувачів. Готовий код можна знайти на Github.
Додатки Heroku
Heroku має безліч готових інструментів та сервісів, які називаються Add-ons (додатки). На сторінці з додатками можна знайти біля 150 сервісів, згрупованих по категоріям: Data Stores, Monitoring, Logging, Caching і т.д. Наприклад, тут є бази даних MySQL, Redis або MongoDB, сервіси повнотекстового пошуку Elasticsearch, стримінгу повідомлень Kafka, генерації PDF, обробки відео і багато іншого.
Ми будемо використовувати сервіс бази даних, який називається Heroku Postgres. Він доступний в декількох планах: від найпростішого Hobby Dev, який обмежений 20-ти одночасними з'єднаннями і 10000-ми рядками, до найбільш потужного Shield 8, який надає 488 GB оперативної пам'яті і 3TB сховища.
Масштабування Heroku Postgres
Heroku Postgres легко масштабується вертикально. Є можливість збільшувати розмір сховища і оперативної пам'яті, в якій знаходиться так званий hot-data-set
, для швидшої оброки запитів. Для вертикального масштабування необхідно просто змінити план використання на вищий. Горизонтальне масштабування в Heroku Postgres можливе завдяки спеціальній конфігурації leader-follower
. Вона дозволяє створювати декілька копій вашої бази даних, доступних лише для читання, які називаються follower
. Дані в цих БД синхронізуються в реальному часі із основною базою, яка в термінології Heroku називається leader
. Heroku забезпечує розташування баз даних follower
та leader
в різних дата-центрах, що підвищує їх надійність і дає можливість продовжити роботу вашій програмі у випадку виходу з ладу частини інфраструктури Heroku.
Нам цілком підйде план Hobby Dev, адже 10000 рядків - це більше ніж достатньо для демострації аутентифікації у веб-програмі. Для даного плану Heroku забезпечує доступність БД на рівні 99.5%. Для вищих планів доступність вища і сягає 99.95%.
Варто додати, що Heroku Postgres доступна у двох регіонах - Північній Америці та Європі. Ми створимо БД у Європі, так як наша веб-програма також розміщена на сервері у Європі.
Створення бази даних
Перейдіть в каталог з проєктом dotnet-app-heroku
, що був створений в попередній статті. Перш за все, необхідно увійти в акаунт Heroku:
> heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/9e58d2b7-dd08-4dca-968e-5ef0ddaf399d
Logging in... done
Logged in as elexander+heroku@ukr.net
Створимо базу даних, вказавши хобі план та ім'я нашої програми в Heroku
> heroku addons:create heroku-postgresql:hobby-dev --app dotnet-app-heroku
Creating heroku-postgresql:hobby-dev on ⬢ dotnet-app-heroku... free
Database has been created and is available
...
Created postgresql-horizontal-81849 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
Heroku записав інформацію про підключення до БД в змінну оточення DATABASE_URL
. Пізніше ми зчитаємо її під час виконання програми і таким чином отримаємо інформацію про адресу серверу, ім'я користувача, його пароль і назву бази даних на сервері Postgres.
Ви не можете самостійно визначити параметри підключення, як ім'я користувача чи пароль, адже Heroku не надає вам окремий сервер бази даних, а дозволяє використовувати сервер спільно з іншими користувачами. До того ж, Heroku може змінити дані підключення, наприклад, адресу серверу, але в такому разі змінна оточення
DATABASE_URL
також буде оновлена. Враховуючи це, не варто зберігати рядок підключення в якомусь іншому місці, а тим більше у вихідному коді програми.
Перевіримо стан нашої бази даних і переконаймося, що план підключення дійсно не вимагає жодних витрат (Price = free):
> heroku addons
Owning App Add-on Plan Price State
───────────────── ─────────────────────────── ─────────────────────────── ───── ───────
dotnet-app-heroku postgresql-horizontal-81849 heroku-postgresql:hobby-dev free created
Налаштування програми для роботи з БД
Тепер, коли база даних створена, необхідно додати аутентифікацію в нашу програму ASP.NET Core. Нам знадобляться додаткові пакети для роботи з Microsoft Identity
та EntityFramework Core
. Їх можна додати командою dotnet add package
:
> dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
> dotnet add package Microsoft.AspNetCore.Identity.UI
> dotnet add package Microsoft.EntityFrameworkCore.Design
> dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
info : PackageReference for package 'Microsoft.AspNetCore.Identity.EntityFrameworkCore' version '3.1.6' added
info : PackageReference for package 'Microsoft.AspNetCore.Identity.UI' version '3.1.6' added
info : PackageReference for package 'Microsoft.EntityFrameworkCore.Design' version '3.1.6' added
info : PackageReference for package 'Npgsql.EntityFrameworkCore.PostgreSQL' version '3.1.4' added
Тепер додамо клас ApplicationDbContext
, це вкрай важлива частина при роботі з EntityFramework і точка доступу до нашої бази даних. Цей клас повинен наслідуватись від IdentityDbContext
, тому що ми хочемо, щоб Microsoft Identity був прив'язаний до нашого контексту, а отже дані користувачів зберігались у створеній нами базі даних.
Створіть новий файл ApplicationDbContext.cs
з таким вмістом:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace DotnetAppHeroku
{
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
}
Наразі EntityFramework не знає як працювати з конкретною базою даних, адже це універсальний фреймворк, що надає функції маппінгу об'єктів C# в записи бази даних. Тож нам необхідно використати відповідний драйвер. Для Postgres найбільш популярним є пакет Npgsql. В цьому дописі ви можете подивитись як підключити базу даних PostgreSQL
з EntityFramework Core
до вашої програми. Як ви бачите, для конфігурації драйверу необхідно передати рядок з'єднання у форматі Host=my_host;Database=my_db;Username=my_user;Password=my_pw
. Де взяти ці данні? Запитаємо конфігурацію нашої програми у Heroku.
> heroku config --app dotnet-app-heroku
=== dotnet-app-heroku Config Vars
DATABASE_URL: postgres://zevxwvnofzdqgh:6fbfa85e483c547461d8dd1b1cdb5c3889ee11016ac278626056d317f20eb590@ec2-52-22-216-69.compute-1.amazonaws.com:5432/d67ogunajtekdt
Як бачите, Heroku створив змінну оточення DATABASE_URL
, але формат рядка з'єднання дещо відрізняється від того, що очікує драйвер Npgsql
. PostgreSQL використовує загальноприйнятий стандарт URL для підключення до БД. Цей формат описаний в документації:
postgresql://[user[:password]@][netloc][:port][,...][/dbname]
Нам необхідно додати трохи коду, щоб перетворити URL, який пропонує Heroku, в конфігурацію з'єднання, яку вимагає EntityFramework.
Додайте файл ConfigurationExtensions.cs
з наступним вмістом:
using System;
using Microsoft.Extensions.Configuration;
namespace DotnetAppHeroku
{
public static class ConfigurationExtensions
{
public static string GetConnectionString(this IConfiguration configuration)
{
var uri = new UriBuilder(configuration["DATABASE_URL"]);
return $"Host={uri.Host};" +
$"Database={uri.Path.Remove(0,1)};" +
$"Username={uri.UserName};" +
$"Password={uri.Password};" +
"sslmode=Require;" +
"Trust Server Certificate=true;";
}
}
}
Два останні параметри sslmode=Require
та Trust Server Certificate=true;
необхідні, адже Heroku підтримує тільки з'єднання, що захищені через SSL.
Маючи метод розширення, що повертає рядок для з'єднання, можемо налаштувати контекст бази даних та сервіси Identity
:
Змініть метод ConfigureServices
у файлі Startup.cs
, щоб він містив дану конфігурацію:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(
Configuration.GetConnectionString()));
services.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
}
Також додайте аутентифікацію в методі Configure
:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
...
app.UseAuthentication();
app.UseAuthorization();
...
Тепер підключення до бази даних налаштоване і ми можемо згенерувати таблиці, індекси та інші об'єкти БД, що потребує Identity
:
> dotnet ef migrations add InitialMigration
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
Застосуємо створену міграцію до бази даних:
> dotnet ef database update
Build started...
Build succeeded.
Done.
Після цього можемо переконатись, що база даних була успішно створена та містить всі необхідні таблиці. Для цього я підключився до бази даних через менеджер HeidiSQL:
Налаштування інтерфейсу аутентифікації
Нам залишилось змінити інтерфейс веб-програми, аби зробити можливою реєстрацію користувача і його наступний вхід:
- Додати новий шаблон для сторінки реєстрації та входу.
- Підключити доданий шаблон до головної сторінки.
- Додати Identity UI до нашої програми.
Тож додамо в папку Pages/Shared
файл _LoginPartial.cshtml
:
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post" >
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
</ul>
У файлі _Layout.cshtml
знайдіть елемент div
з класом "navbar-collapse"
і додайте рядок відразу за ним:
<partial name="_LoginPartial" />
Створіть папку Areas\Identity\Pages\
і в ній файл _ViewStart.cshtml
:
@{
Layout = "/Pages/Shared/_Layout.cshtml";
}
Додайте до файлу імпорту _ViewImports.cshtml
простір імен для Microsoft Identity
:
@using Microsoft.AspNetCore.Identity
Тепер можна виконати build
проєкту і переконатись, що все працює. Зробіть коміт і пуш у репозиторій Heroku. Ваша програма буде автоматично розгорнута (адже ми сконфігурували це в першій статті) і через деякий час доступна за адресою http://dotnet-app-heroku.herokuapp.com/
. Спробуйте зареєструвати нового користувача і потім увійти від його імені:
Статистика використання БД
Давайте переглянемо деяку статистику по базі даних, що дасть нам уявлення про те, як вона використовується і які обмеження порушені:
> heroku pg:info
=== DATABASE_URL
Plan: Hobby-dev
Status: Available
Connections: 1/20
PG Version: 12.3
Created: 2020-07-28 16:28 UTC
Data Size: 8.5 MB
Tables: 8
Rows: 2/10000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
Continuous Protection: Off
Add-on: postgresql-horizontal-81849
Як бачимо, на даний момент є одне з'єднання і використано 8.5 MB сховища. Також створено 8 таблиць і 2 рядки: перший рядок для новоствореного користувача і другий - це запис в таблиці з міграціями EntityFramework Core.
Висновок
Ми побачили, як:
- Створити базу даних
PostgreSQL
вHeroku
. - Налаштувати
EntityFramework Core
таMicrosoft Identity
для роботи з базою даних. - Додати елементи інтерфейсу для реєстрації та входу користувача.
- Переглянути статистику використання бази даних.
Більш детальну інформацію про Heroku Postgres ви можете знайти в офіційній документації.
Оригінальна стаття на моєму сайті.
Top comments (1)
Привіт! Дякую за цю безцінну інформацію. Мені дуже цікаво і корисно було прочитати статтю. Таким чином, ви створите безкоштовну базу даних PostgreSQL на Heroku та налаштуєте її для підтримки процесу аутентифікації у вашій веб-програмі ASP.NET Core. А якщо вирішиш відпочити та відволіктися то sunofegyptgame.com/ це чудовий вибір для тих, хто хоче насолоджуватись яскравою графікою, захоплюючою тематикою та цікавим ігровим процесом. Вельми вдячний вам за цю інструкцію.