A simple site with the ability to log in to node.js
In this article I will try to talk about how to use node.js and connect to make a simple site with authorization. Those. such, where part of the content is available to everyone, and part - only to registered users. Since express.js is based on connect, almost everything that is written here applies to it too.
Let's say that you already know what node.js is and how to work with it. Also suppose that you already have a simple site with a main page and a couple of additional ones. Here are the sources of such a site, an example for this article.
There is such a thing as a session - a period of time while the user is on the site. The session begins when the user first opens the site in the browser and ends when it expires the period of validity (or when a site wants to terminate it). Each session is associated with a specific data set:
To solve our problem, we need two tables in the database: one for storing session data, the other for user information. In fact, in this case it is not entirely correct to say “DB table”, the information may be in different places. For example, all session parameters can be stored in cookies (or in the application’s memory, although this is not good). User data can come from outside if it logs in using OpenID / OAuth.
All the work of creating a session
The order matters, the rules themselves must be defined before defining the routes. The first rule provides for working with cookies in general. The second one adds to the usual
As already mentioned,
In principle, one variable would be enough
When the user wants to log out, it will be enough just to delete the added fields:
For a complete cleanup, there is a session.destroy () method . It deletes
The most obvious solution is to check request.session.authorized whenever you need to generate a secure page. Actually, this is what they do in the article to which I have already referred. The problem is, this contradicts the “layered” ideology
All. Hope this helps someone.
Let's say that you already know what node.js is and how to work with it. Also suppose that you already have a simple site with a main page and a couple of additional ones. Here are the sources of such a site, an example for this article.
Theory
There is such a thing as a session - a period of time while the user is on the site. The session begins when the user first opens the site in the browser and ends when it expires the period of validity (or when a site wants to terminate it). Each session is associated with a specific data set:
- unique session identifier
- validity
- username (if he enters it)
- other service information necessary for identification: ip-address, user agent
- any other information that the site associates with the current user. For example, an electronic store may store in a session a list of products added to the basket.
To solve our problem, we need two tables in the database: one for storing session data, the other for user information. In fact, in this case it is not entirely correct to say “DB table”, the information may be in different places. For example, all session parameters can be stored in cookies (or in the application’s memory, although this is not good). User data can come from outside if it logs in using OpenID / OAuth.
Connect
All the work of creating a session
connecttakes over. To do this, add two rules:app.use(connect.cookieParser());
app.use(connect.session({ secret: 'your secret here'} ));
The order matters, the rules themselves must be defined before defining the routes. The first rule provides for working with cookies in general. The second one adds to the usual
requestfield sessionthrough which the session data will be available (further with examples it will become clearer). connect.sessiongets the following parameters:secret- A phrase that is used to encrypt information in cookies.store- The object that will be used to store session data. By default, connect stores all the data in memory, but, of course, this cannot be done in real applications. There are ready-made solutions for mongodb , redis , MySQL , etc.cookie- set of cookie parameters. The most important ismaxAge, lifetime in milliseconds (or null)
Login
As already mentioned,
connectwill add a field sessionto each request, but by default there is nothing interesting there. If we somehow “recognize” the user (in fact, if he enters the correct password), we will need to add information about him to the session. Something like this:if ((request.body.login==='Thor')&&(request.body.password==='111')) {
request.session.authorized = true;
request.session.username = request.body.login;
console.log('Thor is here!');
}In principle, one variable would be enough
username(as the author of this article does ). But then checking if the user is authorized will look ugly:if (typeof req.session.username == 'undefined') {
// не залогинен, перенаправить на форму ввода пароля
}When the user wants to log out, it will be enough just to delete the added fields:
delete req.session.authorized;
delete req.session.username ;
For a complete cleanup, there is a session.destroy () method . It deletes
sessionfrom the current request, and the next time this field will be regenerated.Access control
The most obvious solution is to check request.session.authorized whenever you need to generate a secure page. Actually, this is what they do in the article to which I have already referred. The problem is, this contradicts the “layered” ideology
connect. It is better to set a special rule that will check the user’s rights and, if something goes wrong, redirect it to the error page. The idea is described here , in our case it will be// адреса, которые поддерживает наш сайт;
var siteUrls = [
{pattern:'^/login/?$', restricted: false}
, {pattern:'^/logout/?$', restricted: true}
, {pattern:'^/$', restricted: false}
, {pattern:'^/single/\\w+/?$', restricted: true}
];
function authorizeUrls(urls) {
function authorize(req, res, next) {
var requestedUrl = url.parse(req.url).pathname;
for (var ui in urls) {
var pattern = urls[ui].pattern;
var restricted = urls[ui].restricted;
if (requestedUrl.match(pattern)) {
if (restricted) {
if (req.session.authorized) {
// если все хорошо, просто переходим к следующим правилам
next();
return;
}
else{
// пользователь не авторизирован, отправляем его на страницу логина
res.writeHead(303, {'Location': '/login'});
res.end();
return;
}
}
else {
next();
return;
}
}
}
// сюда мы попадаем, только если в цикле не нашлось совпадений
console.log('common 404 for ', req.url);
res.end('404: there is no ' + req.url + ' here');
}
return authorize ;
}
app.use('/', authorizeUrls(siteUrls));
All. Hope this helps someone.