از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
مدیریت احراز هویت در Express.jsدر این مقاله، ما قصد داریم یک برنامه ساده بسازیم تا نشان دهیم چگونه می توانید احراز هویت را در Express.js مدیریت کنید. از آنجایی که ما از برخی دستورات اولیه ES6 و چارچوب بوت استرپ برای طراحی رابط کاربری استفاده خواهیم کرد، اگر دانش اولیه در مورد آن فناوری ها داشته باشید، ممکن است به شما کمک کند. زوج…
سرفصلهای مطلب
معرفی
در این مقاله، ما قصد داریم یک برنامه ساده بسازیم تا نشان دهیم چگونه می توانید احراز هویت را در Express.js مدیریت کنید. از آنجایی که ما از برخی دستورات اولیه ES6 و چارچوب بوت استرپ برای طراحی رابط کاربری استفاده خواهیم کرد، اگر دانش اولیه در مورد آن فناوری ها داشته باشید، ممکن است به شما کمک کند.
حتی اگر ممکن است نیاز به استفاده از پایگاه داده در یک برنامه واقعی داشته باشید، از آنجایی که ما باید این مقاله را ساده نگه داریم، از هیچ پایگاه داده یا روش اعتبارسنجی ایمیل مانند ارسال ایمیل با کد اعتبار سنجی استفاده نخواهیم کرد.
راه اندازی پروژه
ابتدا، اجازه دهید یک پوشه جدید به نام، مثلاً، ایجاد کنیم. simple-web-app
. با استفاده از terminal، به آن پوشه می رویم و یک پروژه Node.js اسکلت ایجاد می کنیم:
$ npm init
اکنون می توانیم Express را نیز نصب کنیم:
$ npm install --save express
برای ساده نگه داشتن کارها، از یک موتور رندر سمت سرور به نام استفاده خواهیم کرد دسته دسته. این موتور صفحات HTML ما را رندر می کند روی سمت سرور، به همین دلیل، ما به هیچ چارچوب فرانت اند دیگری مانند Angular یا React نیاز نخواهیم داشت.
بیایید جلو برویم و نصب کنیم express-handlebars
:
$ npm install --save express-handlebars
ما همچنین از دو بسته میانافزار Express دیگر استفاده خواهیم کرد (body-parser
و cookie-parser
) برای تجزیه بدنه های درخواست HTTP و تجزیه کوکی های مورد نیاز برای احراز هویت:
$ npm install --save body-parser cookie-parser
پیاده سازی
برنامه ای که می خواهیم بسازیم حاوی یک “محافظت شده” خواهد بود page که فقط کاربران وارد شده می توانند از آن بازدید کنند، در غیر این صورت، به خانه هدایت می شوند page – از آنها خواسته می شود که وارد سیستم شوند یا ثبت نام کنند.
برای شروع، بیایید import کتابخانه هایی که قبلاً نصب کرده ایم:
const express = require('express');
const exphbs = require('express-handlebars');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
ما از Node’s native استفاده خواهیم کرد crypto
ماژول برای هش رمز عبور و ایجاد یک نشانه احراز هویت – این موضوع کمی بعداً در مقاله توضیح داده خواهد شد.
در مرحله بعد، بیایید یک برنامه Express ساده ایجاد کنیم و میان افزاری را که وارد کرده ایم، در کنار موتور Handlebars پیکربندی کنیم:
const app = express();
// To support URL-encoded bodies
app.use(bodyParser.urlencoded({ extended: true }));
// To parse cookies from the HTTP Request
app.use(cookieParser());
app.engine('hbs', exphbs({
extname: '.hbs'
}));
app.set('view engine', 'hbs');
// Our requests hadlers will be implemented here...
app.listen(3000);
به طور پیش فرض در Handlebars، پسوند قالب باید باشد .handlebars
. همانطور که در این کد مشاهده می کنید، موتور قالب فرمان خود را برای پشتیبانی از فایل ها با آن پیکربندی کرده ایم .hbs
پسوند کوتاه تر حالا بیایید چند فایل قالب بسازیم:
این layouts
پوشه داخل view
پوشه چیدمان اصلی شما را نگه می دارد، که HTML پایه را برای سایر قالب ها فراهم می کند.
بیایید ایجاد کنیم main.hbs
لفاف اصلی ما page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
{{{body}}}
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
سایر قالب ها در داخل رندر می شوند {{{body}}}
برچسب این قالب ما HTML boilerplate و فایل های CSS و JS مورد نیاز را داریم بوت استرپ در این طرح وارد شده است.
پس از انجام بسته بندی اصلی، بیایید آن را ایجاد کنیم home.hbs
page، جایی که از کاربران خواسته می شود وارد سیستم شوند یا ثبت نام کنند:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Simple Authentication App</a>
</nav>
<div style="margin-top: 30px">
<a class="btn btn-primary btn-lg active" href="/login">Login</a>
<a class="btn btn-primary btn-lg active" href="/register">Register</a>
</div>
سپس اجازه دهید یک کنترل کننده درخواست برای مسیر ایجاد کنیم root مسیر (/
) برای رندر کردن قالب خانه.
app.get('/', function (req, res) {
res.render('home');
});
بیایید برنامه خود را راه اندازی کنیم و به آن بروید http://localhost:3000
:
ثبت حساب
اطلاعات مربوط به یک حساب کاربری از طریق a registration.hbs
page:
<div class="row justify-content-md-center" style="margin-top: 30px">
<div class="col-md-4">
{{#if message}}
<div class="alert {{messageClass}}" role="alert">
{{message}}
</div>
{{/if}}
<form method="POST" action="/register">
<div class="form-group">
<label for="firstNameInput">First Name</label>
<input name="firstName" type="text" class="form-control" id="firstNameInput">
</div>
<div class="form-group">
<label for="lastNameInput">Last Name</label>
<input name="firstName" type="text" class="form-control" id="lastNameInput">
</div>
<div class="form-group">
<label for="emailInput">Email address</label>
<input name="email" type="email" class="form-control" id="emailInput" placeholder="Enter email">
</div>
<div class="form-group">
<label for="passwordInput">Password</label>
<input name="password" type="password" class="form-control" id="passwordInput" placeholder="Password">
</div>
<div class="form-group">
<label for="confirmPasswordInput">Confirm Password</label>
<input name="confirmPassword" type="password" class="form-control" id="confirmPasswordInput"
placeholder="Re-enter your password here">
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</div>
در این قالب یک فرم با فیلدهای ثبت نام کاربر ایجاد کرده ایم که نام، نام خانوادگی، آدرس ایمیل، رمز عبور و رمز عبور تایید است و عمل خود را به عنوان /register
مسیر همچنین یک فیلد پیام داریم که در آن پیام های خطا و موفقیت را به عنوان مثال در صورت عدم تطابق رمزهای عبور و غیره نمایش می دهیم.
بیایید یک دسته درخواست ایجاد کنیم تا هنگام بازدید کاربر، الگوی ثبت نام را ارائه دهد http://localhost:3000/register
:
app.get('/register', (req, res) => {
res.render('register');
});
به دلیل نگرانیهای امنیتی، هش رمز عبور با یک رمز عبور قوی روش خوبی است الگوریتم هش پسندیدن SHA256
. با هش کردن گذرواژهها، ما مطمئن میشویم که حتی اگر پایگاه داده رمز عبور ما به خطر بیفتد، گذرواژهها به سادگی در قالب متنی در معرض دید قرار نمیگیرند.
یک روش حتی بهتر از هش کردن ساده استفاده از آن است نمک، مانند با bcrypt الگوریتم برای اطلاعات بیشتر روی برای ایمن کردن احراز هویت، اجرای احراز هویت کاربر به روش صحیح را بررسی کنید. با این حال، در این مقاله، ما چیزها را کمی ساده تر نگه می داریم.
const crypto = require('crypto');
const getHashedPassword = (password) => {
const sha256 = crypto.createHash('sha256');
const hash = sha256.update(password).digest('base64');
return hash;
}
هنگامی که کاربر فرم ثبت نام را ارسال می کند، الف POST
درخواست به /register
مسیر.
همانطور که گفته شد، اکنون باید آن درخواست را با اطلاعات فرم رسیدگی کنیم و کاربر تازه ایجاد شده خود را ادامه دهیم. معمولاً، این کار با ماندگاری کاربر در پایگاه داده انجام میشود، اما برای سادگی، کاربران را در یک آرایه جاوا اسکریپت ذخیره میکنیم.
از آنجایی که هر راهاندازی مجدد سرور، آرایه را مجدداً مقداردهی اولیه میکند، یک کاربر را برای اهداف آزمایشی سختکد میکنیم تا هر بار مقداردهی شود:
const users = (
// This user is added to the array to avoid creating a new user روی each restart
{
firstName: 'John',
lastName: 'Doe',
email: '(email protected)',
// This is the SHA256 hash for value of `password`
password: 'XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg='
}
);
app.post('/register', (req, res) => {
const { email, firstName, lastName, password, confirmPassword } = req.body;
// Check if the password and confirm password fields match
if (password === confirmPassword) {
// Check if user with the same email is also registered
if (users.find(user => user.email === email)) {
res.render('register', {
message: 'User already registered.',
messageClass: 'alert-danger'
});
return;
}
const hashedPassword = getHashedPassword(password);
// Store user into the database if you are using one
users.push({
firstName,
lastName,
email,
password: hashedPassword
});
res.render('login', {
message: 'Registration Complete. Please login to continue.',
messageClass: 'alert-success'
});
} else {
res.render('register', {
message: 'Password does not match.',
messageClass: 'alert-danger'
});
}
});
دریافت شده email
، firstName
، lastName
، password
، و confirmPassword
معتبر هستند – رمزهای عبور مطابقت دارند، ایمیل قبلاً ثبت نشده است و غیره.
اگر هر اعتبارسنجی موفقیت آمیز باشد، رمز عبور را هش می کنیم و اطلاعات را در داخل آرایه ذخیره می کنیم و کاربر را به لاگین هدایت می کنیم. page. در غیر این صورت ثبت نام را مجدداً انجام می دهیم page با پیغام خطا
حال، بیایید بازدید کنیم /register
نقطه پایانی برای تأیید درستی کارکرد آن:
ورود به حساب کاربری
با خارج شدن از ثبت نام، میتوانیم عملکرد ورود را پیادهسازی کنیم. بیایید با ساختن شروع کنیم login.hbs
page:
<div class="row justify-content-md-center" style="margin-top: 100px">
<div class="col-md-6">
{{#if message}}
<div class="alert {{messageClass}}" role="alert">
{{message}}
</div>
{{/if}}
<form method="POST" action="/login">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input name="email" type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input name="password" type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</div>
و سپس، اجازه دهید یک کنترل کننده برای آن درخواست نیز ایجاد کنیم:
app.get('/login', (req, res) => {
res.render('login');
});
این فرم یک را ارسال خواهد کرد POST
درخواست به /login
زمانی که کاربر فرم را ارسال می کند. با این حال، کار دیگری که ما انجام خواهیم داد ارسال یک است نشانه احراز هویت برای ورود این نشانه برای شناسایی کاربر استفاده می شود و هر بار که درخواست HTTP ارسال می کند، این نشانه به عنوان یک کوکی ارسال می شود:
const generateAuthToken = () => {
return crypto.randomBytes(30).toString('hex');
}
با روش کمکی خود، می توانیم یک کنترل کننده درخواست برای ورود ایجاد کنیم page:
// This will hold the users and authToken related to users
const authTokens = {};
app.post('/login', (req, res) => {
const { email, password } = req.body;
const hashedPassword = getHashedPassword(password);
const user = users.find(u => {
return u.email === email && hashedPassword === u.password
});
if (user) {
const authToken = generateAuthToken();
// Store authentication token
authTokens(authToken) = user;
// Setting the auth token in cookies
res.cookie('AuthToken', authToken);
// Redirect user to the protected page
res.redirect('/protected');
} else {
res.render('login', {
message: 'Invalid username or password',
messageClass: 'alert-danger'
});
}
});
در این کنترل کننده درخواست، نقشه ای فراخوانی می شود authTokens
برای ذخیره توکن های احراز هویت به عنوان کلید و کاربر مربوطه به عنوان مقدار استفاده می شود که امکان جستجوی یک توکن ساده را برای کاربر فراهم می کند. می توانید از پایگاه داده ای مانند استفاده کنید ردیس، یا واقعاً، هر پایگاه داده ای برای ذخیره این نشانه ها – ما از این نقشه برای سادگی استفاده می کنیم.
ضربه زدن به /login
نقطه پایانی، از ما استقبال می شود:
با این حال، ما هنوز کاملاً تمام نشده ایم. ما باید با خواندن درخواست به کاربر تزریق کنیم authToken
از کوکی ها پس از دریافت درخواست ورود به سیستم. بالاتر از همه گردانندگان درخواست و زیر cookie-parser
میان افزار، بیایید میان افزار سفارشی خود را برای تزریق کاربران به درخواست ها ایجاد کنیم:
app.use((req, res, next) => {
// Get auth token from the cookies
const authToken = req.cookies('AuthToken');
// Inject the user to the request
req.user = authTokens(authToken);
next();
});
حالا میتونیم استفاده کنیم req.user
در کنترل کننده های درخواست ما برای بررسی اینکه آیا کاربر از طریق یک توکن احراز هویت شده است یا خیر.
در نهایت، اجازه دهید یک کنترل کننده درخواست ایجاد کنیم تا محافظت شده را ارائه دهد page – protected.hbs
:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Protected Page</a>
</nav>
<div>
<h2>This page is only visible to logged in users</h2>
</div>
و یک کنترل کننده درخواست برای page:
app.get('/protected', (req, res) => {
if (req.user) {
res.render('protected');
} else {
res.render('login', {
message: 'Please login to continue',
messageClass: 'alert-danger'
});
}
});
همانطور که می بینید، می توانید استفاده کنید req.user
برای بررسی اینکه آیا کاربر احراز هویت شده است یا خیر. اگر آن شی خالی باشد، کاربر احراز هویت نمی شود.
راه دیگری برای نیاز به احراز هویت روی routes این است که آن را بهعنوان میانافزار پیادهسازی کنید، که سپس میتوان آن را مستقیماً به مسیرهایی که با آن تعریف شدهاند اعمال کرد app
هدف – شی:
const requireAuth = (req, res, next) => {
if (req.user) {
next();
} else {
res.render('login', {
message: 'Please login to continue',
messageClass: 'alert-danger'
});
}
};
app.get('/protected', requireAuth, (req, res) => {
res.render('protected');
});
استراتژیهای مجوز را نیز میتوان با تخصیص نقشها به کاربران و سپس بررسی مجوزهای صحیح قبل از دسترسی کاربر به این روش پیادهسازی کرد. page.
نتیجه
احراز هویت کاربر در Express بسیار ساده و سرراست است. ما از Node’s native استفاده کرده ایم crypto
ماژول برای هش رمز عبور کاربران ثبت نام شده به عنوان یک ویژگی ایمنی اساسی، و ایجاد یک محافظت شده است page، فقط برای کاربرانی که با یک توکن احراز هویت شده اند قابل مشاهده است.
کد منبع این پروژه را می توان یافت روی GitHub.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-23 09:15:03