ساخت یک وبسایت با احراز هویت کاربر و مدیریت (ورود، ثبت نام، بازنشانی رمز عبور و...) میتوانند یک عذاب بزرگ باشند. به عنوان یک توسعهدهنده، میلیونها مسئله ریز وجود دارند که باید نگران آنها باشید:
- ذخیرهسازی کاربران در دیتابیس خود
- مطمئن شدن از این که ویژگیهای صحیح را برای کاربر تعیین کردهاید
- اجبار کاربران برای وارد شدن به یک صفحه
- ساخت فرمهای ثبت نام و ورود
- ساخت روند بازنشانی رمز عبور که به کاربر یک لینک را ایمیل میکند
- تایید کاربران جدید، وقتی که از طریق ایمیل ثبت نام میکنند
- و...
این لیست همچنان ادامه دارد.
امروز فقط میخواهم به شما نشان دهم که چگونه میتوانید یک وبسایت Node.js که تمام موارد بالا را پشتیبانی میکند را سریعا بسازید. به شما خواهم گفت که پشت پرده دقیقا چه اتفاقاتی میافتد، تا بتوانید کاملا نحوه کار احراز هویت کاربر را درک کنید.
اگر کنجکاو بودید که احراز هویت کاربر چگونه کار میکند، عاشق این مقاله خواهید شد.
جدول محتویات:
- چیزی که ما خواهیم ساخت
- ابزار را نصب کنید
- سرور مجوز دهی خود را راهاندازی کنید
- مدیریت Session را پیکربندی کنید
- Viewهای Express.js را بسازید
چیزی که ما خواهیم ساخت:
همانطور که پیشتر اشاره کردم، در این مقاله یک وبسایت Node.js ساده که چند ویژگی کلیدی مانند موارد زیر را پیشتیبانی کند، خواهیم ساخت:
- ثبت نام کاربر
- ورود کاربر
- بازنشانی رمز عبور
- تاییدیه ایمیل
پروژه پایانی این مقاله به این صورت خواهد بود:
این وبسایت، با استفاده از چند ابزار ساخته خواهد شد:
- Express.js - معروفترین فریموورک در اکوسیستم Node.js.
- express-session - یک کتابخانه مدیریت session معروف. این ابزاری است که ما را قادر میسازد تا کوکیهایی بسازیم، که به یاد دارند چه کسی یک کاربر است.
- Pug - یک زبان الگونویسی معروف که نوشتن HTML را کمی سادهتر میکند.
- oidc-middleware - یک کتابخانه توسعهدهنده معروف که مدیریت احراز هویت با استفاده از OpenID Connect را آسانتر میکند.
ابزار را نصب کنید:
اولین کاری که باید انجام دهید، نصب تمام ابزار اوپن سورسی است که در ساخت این وبسایت Node.js استفاده خواهیم کرد.
در ابتدا، ابزار express-generator را نصب کنید. این ابزار، رسما ابزار Bootstrapping پشتیبانی شده برای شروع کار سریع با Express.js است.
npm install express-generator@4.16.0
وقتی که این کار به اتمام رسید، باید وبسایت Express.js خود را با استفاده از express-generator بسازید.
express --view pug login-portal
cd login-portal
npm install
حال یک وبسایت Express.js ساده دارید که میتوانید اجرا کرده، و آزمایش کنید. وب سرور جدید خود را با دستور npm start شروع کرده، و به آدرس http://localhost:3000 بر روی مرورگر خود بروید تا مطمئن شوید که همه چیز درست کار میکند. اگر همه چیز درست باشد، چنین صفحهای را خواهید دید:
سپس، چند پکیح اضافی نصب کنید. ما از این پکیجها در ادامه آموزش استفاده خواهیم کرد. نصب پیشاپیش آنها، کار ما را بعدا آسانتر میکند.
برای نصب این Dependencyها، این دستور را در ترمینال خود اجرا کنید:
npm install express-session@1.15.6
npm install @okta/oidc-middleware@0.1.3
npm install @okta/okta-sdk-nodejs@1.1.0
حال، به کار خود ادامه میدهیم.
سرور مجوز دهی خود را راهاندازی کنید:
از نظر تاریخی، پیادهسازی احراز هویت وب همیشه کمی سخت بوده است. در گذشته، همه مردم الگوهای احراز هویت را به روشهای مختلف و خودسرانه پیادهسازی میکردند. گرچه در طی سالهای اخیر، همه چیز با معرفی و رشد معروفیت OpenID Connect تغییر کرده است.
یکی از بخشهای هستهای در OpenID Connect، authorization server (سرور احراز هویت) است. یک سرور احراز هویت، جایی است که به تمام جریانات ورود کاربران در برنامه شما رسیدگی میشود. هدف این است که برنامه به سرور احراز هویت منتقل شود، تا ورود کاربران را پردازش کند. سپس سرور احراز هویت پس از این که کاربر مورد نظر احراز هویت شد، او را به وبسایت شما بر میگرداند.
سرورهای احراز هویت مدیریت کاربر را به طور قابل ملاحظهای سادهتر میکنند و درصد ریسک را پایین میآورند. پس این کاری است که در این مقاله انجام خواهیم داد: از یک Provider سرور احراز هویت (Okta) برای ساده و امن کردن پردازش استفاده میکنیم.
استفاده از Okta آسان است و شما را قادر میسازد تا کاربران، سرورهای احراز هویت و بسیاری موارد دیگر را ساخته، و مدیریت کنید، تا احراز هویت وب را آسانتر کنید.
برای شروع راهاندازی سرور احراز هویت، باید یک حساب کاربری رایگان در Okta، با استفاده از لینک http://developer.okta.com/signup/ بسازید. پس از این که حساب خود را ساخته و وارد شدید، اقدام زیر را دنبال کرده، Okta را پیکربندی کنید و سپس میتوانید شروع به کدنویسی کنید.
قدم اول: Org URL خود را ذخیره کنید
اولین کاری باید انجام دهید، این است که Org URL را از بالا سمت راست صفحه در داشبورد Okta خود کپی کنید. این URL برای route کردن سرور احراز هویت شما، برقرای ارتباط با آن و... استفاده خواهد شد. بعدا به این آدرس نیاز خواهید داشت، پس آن را فراموش نکنید.
قدم ۲: یک برنامه OpenID Connect بسازید
Okta شما را قادر میسازد تا کاربرانی برای چندین برنامه که در حال ساخت هستید را ذخیره کرده، و مدیریت کنید. این به این معنی است که قبل از این که بتوانیم ادامه دهیم، باید یک برنامه OpenID Connect جدید برای این پروژه بسازید.
برنامهها در OpenID Connect یک نام کاربری و رمز عبور (که با نامهای Client ID و Client Secret شناخته میشوند) دارند که سرور احراز هویت شما را قادر میسازند تا تشخیص دهد که در هر زمان، با کدام برنامه در حال صحبت است.
برای ساخت یک برنامه جدید، به تب Applications بروید و بر روی Add Application کلیک کنید.
سپس، بر روی گزینه پلتفرم Web کلیک کنید. (زیرا این یک پروژه وب است)
در صفحه تنظیمات، این مقادیر را وارد کنید:
- Name: login-portal
- Base URIs: http://localhost:3000
- Login redirect URIs: http://localhost:3000/users/callback
میتوانید باقی مقادیر را دست نخورده باقی بگذارید.
حال که برنامه مورد نظر ساخته شده است، مقادیر Client ID و Client Secret را در صفحه پیش رو کپی کنید؛ زیرا بعدا در طی کدنویسی به آنها نیاز خواهید داشت.
قدم ۳: یک نشانه احراز هویت بسازید
برای دسترسی به APIهای Okta و مدیریت حسابهای کاربران خود، باید یک نشانه احراز هویت Okta (Okta authentication token) نیز بسازید. این یک کلید API است که بعدا برای ارتباط با APIهای Okta استفاده خواهد شد و شما را قادر میسازد تا کارهایی مانند موارد زیر را انجام دهید:
- ساخت، بروزرسانی و حذف کاربران
- ساخت، بروزرسانی و حذف گروهها
- مدیریت تنظیمات برنامه
- و...
برای ساخت یک نشانه، بر روی تب API در بالای صفحه کلیک کنید. به نشانه خود یک نام بدهید؛ ترجیحا همان نامی که به برنامه خود دادید. سپس بر روی Create Token کلیک کنید. پس از این که نشانه شما ساخته شد، مقدار token را کپی کنید؛ زیرا بعدا به آن نیاز خواهید داشت.
قدم ۴: ثبت نام کاربر را فعالسازی کنید
آخرین مرحله راهاندازی که باید انجام دهید، فعال سازی عملکرد سرور احراز هویت برای فعال سازی ثبت نام کاربر است. به طور معمول، سرورهای احراز هویت فقط از ورود، خروج و موارد این چنینی پشتیبانی میکنند. اما سرور احراز هویت Okta ثبت نامهای Self-service را پشتیبانی میکنند، که کاربران آنها میتوانند حسابهای خود را ساخته، به آنها وارد شوند، رمز عبور خود را بازنشانی کنند و عملا هر کاری که میخواهند را بدون نیاز به کدنویسی شما انجام دهند.
در داشبورد Okta، دکمه کوچکی به نام <> Developer Console در بالا سمت چپ صفحه میبینید. موس را بر روی آن نگه داشته، و گزینه Classic UI که نمایان میشود را انتخاب کنید.
سپس، موس را بر روی تب Directory در بالای صفحه ببرید و سپس گزینه Self-Service Registration را انتخاب کنید. در این صفحه، بر روی دکمه Enable Registration کلیک کنید.
در صفحه پیکربندی، تمام مقادیر به جز گزینه Default redirect را در همان حالت پیشفرض رها کنید. برای این گزینه، بر روی رادیوباکس Custom URL کلیک کنید و http://localhost:3000/dashboard را به عنوان مقدار آن قرار دهید.
این تنظیمات، به سرور احراز هویت میگویند که پس از این که کاربر به طور موفقیت آمیز یک حساب را در وبسایت شما ساخت، او را به کجا منتقل کند.
پس از این که بر روی Save کلیک کرید، آخرین کاری که باید انجام دهید، بازگشت به کنسول Developer است.
موس را بر روی دکمه Classis UI در بالا سمت راست صفحه ببرید و گزینه <> Developer Console را از منوی کشویی انتخاب کنید.
مدیریت Session را پیکربندی کنید:
حال که تمام مراحل راهاندازی تمام شدهاند، بیایید شروع به کدنویسی کنیم.
اولین چیزی که به این وبسایت Express.js اضافه خواهیم کرد، پشتیبانی از Sessionها با استفاده از کتابخانه express-session است.
مدیریت Session، هسته هر سیستم احراز هویتی است. این چیزی است که یک کاربر را قادر می سازد تا در وبسایت شما باقی بماند و مجبور نشود قبل از مشاهده هر صفحه، همه چیز را از اول وارد کند امنترین روش برای مدیریت session کاربران، از طریق کوکیهای سمت سرور است، که علت استفاده از کتابخانه express-session نیز همین است: این کتابخانه شما را قادر میسازد تا کوکیهای سمت سرور را ساخته و مدیریت کنید.
برای شروع، فایل ./app.js را در ویرایشگر خود (که من neovim را ترجیح میدهم) باز کنید و کتابخانه session را به همراه موارد دیگر، بر روی فایل وارد کنید. فایل app.js قلب وبسایت Express.js شما است. این فایل وب سرور Express.js را راهاندازی میکند، تنظیمات را در خود دارد، و...
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require("express-session");
سپس، باید کتابخانه cookie-parser که express-generator را به طور پیشفرض دارد، حذف کنید؛ زیرا از آن استفاده نخواهیم کرد. در فایل ./app.js، این دو خط کد را حذف کنید:
var cookieParser = require('cookie-parser');
// و…
app.use(cookieParser());
حال تنها کاری که باید انجام دهید، وارد کردن کتابخانه express-session به فایل ./app.js است.
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'LONG_RANDOM_STRING_HERE',
resave: true,
saveUninitialized: false
}));
مطمئن شوید که LONG_RANDOM_STRING_HERE با یک رشته واقعی جایگزین کنید. این رشته، چیزی است که کوکیهای کاربران شما را از لو رفتن محافظت میکند.
این کتابخانه session، موارد زیادی را پشت پرده مدیریت میکند:
- کوکیهای امن و Cryptographic Signed شدهای میسازد که میتوانید در مرورگر یک کاربر ذخیره کنید. Cryptographic Signing تکنیکی است که شما را قادر میسازد تا به سرور بگویید که یک کاربر تلاش کرده است تا کوکیها را دستکاری کند، یا نه.
- یک API ساد برای ساخت و حذف کوکیها برای شما به ارمغان میآورد.
- شما را قادر میسازد تا کوکیها را بر اساس نیازهای خود، دستکاری کرده و پیکربندی کنید.
Viewهای Express.js را بسازید:
کار بعدی، ساخت viewهای Express.js است. Viewها در Expres.js چیزی بیش از الگوهای HTML که میخواهیم به یک کاربر نشان دهیم، نیستند. اما بر خلاف HTML معمولی، از زبان الگونویسی Pug برای ساخت viewها استفاده خواهیم کرد.
Pug یکی از معروفترین زبانهای الگونویسی در اکوسیستم Node.js است؛ زیرا شما را قادر میسازد تا کد HTML خلاصه شدهتری بنویسید، از متغیرها استفاده کنید و...
View طرح اصلی را بسازید
اولین (و مهمترین) view که خواهیم ساخت، ./views/layout.pug است. این view پایه ما است که تمام viewهای دیگر آن را از آن گسترده خواهند شد.
در این view، layout پایه تمام صفحات، نوار راهنمایی و... را تعریف خواهیم کرد. فایل ./views/layout.pug را باز کرده، و این کد را با محتویات آن جایگزین کنید.
block variables
doctype html
html(lang="en")
head
meta(charset="utf-8")
meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous")
link(rel="stylesheet", href="/stylesheets/style.css")
title okta-express-login-portal: #{title}
body
div.top-bar.d-flex.flex-column.flex-md-row.align-items-center.p-3.px-md-4.mb-3.bg-white.border-bottom.box-shadow
h5.my-0.mr-md-auto.font-weight-normal
a(href="/", title="Expresso") okta-express-login-portal
nav.my-2.my-md-0.mr-md-3
a.p-2.text-dark(href="/", title="Home") Home
if user == undefined
a.p-2.text-dark(href="/users/login") Log In / Register
else
a.p-2.text-dark(href="/dashboard") Dashboard
a.p-2.text-dark(href="/users/logout") Logout
.container
block content
footer.
Built with #[a(href="https://expressjs.com/") Express.js], login powered by #[a(href="https://developer.okta.com/") Okta].
اگر با HTML آشنا باشید، میتوانید ببینید که Pug بسیار شبیه به HTML است، ولی به جای تگها، از whitespace استفاده میکند. (مانند زبان برنامهنویسی پایتون)
این view کاری جز رندر کردن یک صفحه ساده با یک نوار راهنما در بالا، یک footer در پایین و دو ساختار خاص، یعنی block variables و block content انجام نمیدهد.
خط block variables در بالای فایل، یعنی این که هر کدام از الگوهایی که از این مورد به دست میآیند، میتوانند برخی متغیرها را به صفحه وارد کنند. ممکن است متوجه شده باشید که تگ title دارای یک متغیر است: #{title} - این یکی از متغیرهایی است که یک الگوی فرزند، بعدا میتواند آن را بازنویسی کند.
آیا متوجه خط block content درست بالای footer شدید؟ این بلوک یک الگوی فرزند را قادر میسازد تا HTML را به الگوی layout ما دقیقا در جای مناسب وارد کند. به این صورت، الگوی فرزند ما نیازی ندارند که یک نوار راهنما، header صفحه یا... را دوباره تعریف کنند.
با استفاده از بلوکهای variables و content، الگوهای فرزند ما میتوانند صفحات کاملی با یک title و مقداری محتویات بدنه بسازند.
View هومپیج را بسازید
View بعدی که میسازیم، ./views/index.pug است. فایل مربوطه را باز کرده، و این کد را در آن قرار دهید:
extends layout
block variables
- var title = "Home"
block content
h2.text-center Express App
.row
.offset-sm-2.col-sm-8
.jumbotron.text-center.
Welcome to your new Express app! Please visit the
#[a(href="https://github.com/rdegges/okta-express-login-portal", title="okkta-express-login-portal on GitHub") GitHub page] to learn more.
به خط extends layout در بالا دقت کنید. این خطی است که به pug میگوید که این الگو، فرزند الگوی layout است که پیشتر ساختیم.
در بخش block variables، متغیر title خود را که در الگوی layout برای خروجیدهی عنوان استفاده خواهد شد، تعریف میکنیم و در بخش block content، کد HTML مربوط به بقیه صفحه را وارد میکنیم.
همانطور که میتوانید ببینید، استفاده از الگوها در Pug بسیار ساده است.
View داشبورد را بسازید
View بعدی که باید بسازیم، view داشبورد است. این صفحهای است که کاربران پس از وارد شدن به وبسایت خواهند دید. فایل ./views/dashboard.pug را باز کرده و این کد را در آن قرار دهید:
extends layout
block variables
- var title = "Dashboard"
block content
h2.text-center Dashboard
.row
.offset-sm-2.col-sm-8
.jumbotron.text-center.
Welcome to your dashboard page, #{user.profile.firstName}.
دقت کنید که در این الگو یک متغیر جدید استفاده میشود: #{user}. این متغیر، همانطور که در ادامه خواهید دید، نمایانگر کاربر فعلی است.
ساخت viewهای Error
دو view آخر که باید بسازید، برای مدیریت خطاها هستند.
فایل ./views/error.pug را باز کرده و این کد را در آن قرار دهید:
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}
این کد، زمانی که یک کاربر بر روی یک URL که وجود ندارد کلیک میکند، (404) یا وقتی که یک وب سرور مشکلی دارد (5XX) رندر میشود.
همچنین باید فایلی به نام ./views/authenticated.pug بسازید و کد زیر را در آن قرار دهید. این view، زمانی که یک کاربر از صفحهای بازدید میکند و برای این کار باید وارد شده باشد، نمایش داده میشود.
extends layout
block variables
- var title = "Unauthenticated"
block content
h2.text-center You Must Log In to View This Page
p.text-center.
You must be signed in to view this page. Please #[a(href="/users/login", title="Login") login or register] to view this page.
در بخش بعدی، با ساخت routeهای عمومی شروع کرده، و به ادامه آموزش میرسیم.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید