Hệ thống đăng nhập và đăng ký là các thành phần cơ bản và với tư cách là nhà phát triển, bạn phải triển khai các hệ thống đó cho các dự án khách hàng, dự án nguồn mở hoặc dự án đại học
Trong hướng dẫn này, chúng ta sẽ học cách xây dựng một hệ thống đăng nhập và đăng ký đơn giản và hiệu quả. Chúng tôi sẽ sử dụng các công nghệ sau
- Nút - Để xây dựng Dịch vụ
- MongoDB – Để lưu trữ người dùng
- Redis – để xử lý phiên
- Bootstrap và jQuery – cho giao diện người dùng đơn giản
Bạn cần cài đặt phần mềm sau trong hệ thống của mình trước khi tiếp tục
- Nút v11. 15. 0 hoặc cao hơn/li>
- MongoDB v4. 0. 3 hoặc cao hơn
- làm lại v3. 0. 7 hoặc cao hơn
Khi bạn đã cài đặt xong, chúng ta có thể tiếp tục
Những gì chúng ta sẽ xây dựng?
Chúng tôi sẽ xây dựng một hệ thống đăng nhập và đăng ký người dùng đơn giản bằng Node và MongoDB. Kiểm tra kết quả cuối cùng
trang đăng ký
Trang đăng nhập
trang hồ sơ người dùng
Tôi khuyên bạn nên sao chép kho lưu trữ và tham khảo mã cùng với hướng dẫn
bản sao git https. //github. com/codeforgeek/đăng nhập-đăng ký-hệ thống-mongodb
Hãy bắt đầu nào
MongoDB và Redis
Sau khi cài đặt MongoDB và Redis, bạn cần chạy các chương trình máy chủ cơ sở dữ liệu
Để chạy chương trình máy chủ MongoDB, hãy chạy lệnh sau
mongod --dbpath=
Để chạy chương trình máy chủ Redis, hãy chạy lệnh sau
redis-server
Hãy tiếp tục và tạo dịch vụ của chúng tôi bằng Node
Xây dựng hệ thống đăng nhập và đăng ký người dùng bằng Node
Tạo một dự án Node mới bằng lệnh sau
npm init --y
Cài đặt các phụ thuộc cần thiết bằng lệnh sau
cài đặt npm --save express express-session redis connect-redis nconf mongoose body-parser phấn ejs @hapi/joi
Tạo một tệp mới và đặt tên là config. json. Chúng tôi sẽ lưu trữ cấu hình ứng dụng trong tệp này
cấu hình. json
{
"mongodbURL". "mongodb. //máy chủ cục bộ. 27017/userDemo",
"redisHost". "máy chủ cục bộ",
"redisPort". 6379,
"bí mật phiên". "băm bí mật nào đó",
"cổng". 3000,
"env". "phát triển"
}
Tiếp theo, chúng tôi sẽ tạo tệp nhập i. ứng dụng điện tử. js
ứng dụng. js
const express = yêu cầu ["express"];
const = yêu cầu ["express-session"];
const redis = yêu cầu ["redis"];
const redisStore = yêu cầu ["connect-redis"][session];
const nconf = yêu cầu ["nconf"];
const bodyParser = yêu cầu ["body-parser"];
const phấn = yêu cầu ["chalk"];
const = yêu cầu ["path"];
const ứng dụng = express [];
// tải tập tin cấu hình
nconf
.argv[]
.vi[]
.tệp[{
tệp . __dirname + "/config. json",
}];
// kết nối với cửa hàng phiên redis
const redisSessionStore = redis. createClient[
nconf. nhận["redisPort"],
nconf. nhận["redisHost"],
{
db . 0,
}
];
redisSessionStore. bật["kết nối", [] => {
bảng điều khiển. nhật ký[
`$ { phấn. xanh["✓"]} Connected to ${chalk.xanh["Redis"]} Session Store`
];
}];
ứng dụng. sử dụng[ bodyParser. json[]];
ứng dụng. sử dụng[ bodyParser. được mã hóa url[{ mở rộng . false }]];
// cửa hàng phiên
ứng dụng. sử dụng[
phiên [{
bí mật . nconf. lấy["sessionSecret"],
cookie . {
Tuổi tối đa . 1000 * 60 * 60 * 24 * 7, // 1 week
},
cửa hàng . mới redisStore [{ khách hàng . : redisSessionStore }],
lưu lại . sai,
lưuChưa khởi tạo . sai,
}]
];
// thiết lập đường dẫn tĩnh
ứng dụng. đặt["lượt xem", path.tham gia[ __dirname , "]];
ứng dụng. công cụ["html", require["ejs"].renderFile];
// tuyến đường
ứng dụng. sử dụng["/", require["./routes/static"]];
ứng dụng. sử dụng["/users", require["./routes/users"]];
// khởi động ứng dụng
ứng dụng. nghe này[ nconf. lấy["cổng"] || 3000];
bảng điều khiển. log["Ứng dụng đã bắt đầu. "];
Đầu tiên, chúng tôi đang tải cấu hình của mình. tập tin json. Chúng tôi sẽ sử dụng biến cấu hình trong toàn bộ ứng dụng
Tiếp theo, chúng tôi đang tạo kết nối với Redis và sau đó chuyển kết nối tới phiên cấp tốc
Trong môi trường sản xuất, bạn phải luôn sử dụng cửa hàng phiên bên ngoài, chẳng hạn như Redis
Hãy bắt đầu và tạo các bộ định tuyến cho ứng dụng của chúng ta, tạo một thư mục mới và đặt tên cho nó là các tuyến đường. Tạo hai tệp mới trong đó và đặt tên là tĩnh. js và người dùng. js
Đây là mã của từng tệp bộ định tuyến
tĩnh. js
const express = yêu cầu ["express"];
const ứng dụng = express [];
const bộ định tuyến = express. Bộ định tuyến[];
// định tuyến tĩnh
bộ định tuyến. lấy["/", [req, res] => {
nếu [ req. phiên . người dùng] {
return res. chuyển hướng["/home"];
}
độ phân giải. render["index. html"];
}];
bộ định tuyến. lấy["/home", function [req, res] {
nếu [ req. phiên . người dùng] {
return res. kết xuất["nhà. html", { tên . yêu cầu. phiên . người dùng . tên }];
}
độ phân giải. chuyển hướng["/"];
}];
mô-đun. xuất = bộ định tuyến ;
tĩnh. js
const express = yêu cầu ["express"];
const bộ định tuyến = express. Bộ định tuyến[];
const joi = yêu cầu ["@hapi/joi"];
const mô hình = yêu cầu ["../models/users"];
bộ định tuyến. bài đăng["/đăng nhập", async [req, res] => {
thử {
const giản đồ = joi. đối tượng[] . phím[{
email . tham gia. chuỗi[] . email[] . bắt buộc[],
mật khẩu . tham gia. chuỗi[] . phút[6] . tối đa[20] . bắt buộc[],
}];
const kết quả = giản đồ. xác thực[ yêu cầu. cơ thể];
nếu [ kết quả. lỗi] {
ném kết quả. lỗi . chi tiết[0] . thông báo;
}
hãy để checkUserLogin = chờ đợi các mô hình. xác minh người dùng[ kết quả. giá trị];
if [ checkUserLogin. lỗi] {
ném kiểm tra Đăng nhập người dùng. thông báo;
}
// đặt phiên cho người dùng đã đăng nhập
yêu cầu. phiên . người dùng = {
tên . checkUserLogin. dữ liệu . tên,
email . checkUserLogin. dữ liệu . email,
};
độ phân giải. json[ checkUserLogin ];
} bắt [ e ] {
độ phân giải. json[{ lỗi . true, thông báo . e }];
}
}];
bộ định tuyến. đăng["/đăng ký", async [req, res] => {
thử {
const giản đồ = joi. đối tượng[] . phím[{
tên . tham gia. chuỗi[] . phút[3] . tối đa[45] . bắt buộc[],
email . tham gia. chuỗi[] . email[] . bắt buộc[],
mật khẩu . tham gia. chuỗi[] . phút[6] . tối đa[20] . bắt buộc[],
}];
const kết quả = giản đồ. xác thực[ yêu cầu. cơ thể];
nếu [ kết quả. lỗi] {
ném kết quả. lỗi . chi tiết[0] . thông báo;
}
hãy để addUserResponse = chờ các mô hình. addUser[ kết quả. giá trị];
độ phân giải. json[ addUserResponse ];
} bắt [ e ] {
độ phân giải. json[{ lỗi . true, thông báo . e }];
}
}];
bộ định tuyến. lấy["/đăng xuất", [req, res] => {
nếu [ req. phiên . người dùng] {
yêu cầu. phiên . hủy[];
}
độ phân giải. chuyển hướng["/"];
}];
mô-đun. xuất = bộ định tuyến ;
Chúng tôi đang sử dụng mô-đun joi để xác thực dữ liệu đến từ giao diện người dùng. Nếu dữ liệu đến được xác thực hợp lệ, thì chúng tôi sẽ gọi chức năng cơ sở dữ liệu của mình
Hãy tạo các chức năng cơ sở dữ liệu của chúng tôi. Tạo một thư mục mới và đặt tên là models. Tạo một tệp mới và đặt tên cho nó là kết nối. js
sự liên quan. js
const cầy mangut = yêu cầu ["mongoose"];
const nconf = yêu cầu ["nconf"];
const phấn = yêu cầu ["chalk"];
cầy mangut. kết nối[ nconf. lấy["mongodbURL"], {
useNewUrlParser . true,
sử dụng Cấu trúc liên kết hợp nhất . true,
}];
// xác thực kết nối MongoDB
const db = cầy mangut. kết nối;
// sự kiện
db. bật["lỗi", [] => {
bảng điều khiển. log["Lỗi kết nối MongoDB"];
quy trình. thoát[0];
}];
db. một lần["mở", function [callback] {
bảng điều khiển. nhật ký[
`$ { phấn. xanh["✓"]} Connected to ${chalk.xanh lục["MongoDB"]} Store`
];
}];
mô-đun. xuất = {
mongoConnection . db ,
};
Trong mã hiển thị ở trên, chúng tôi đang tạo kết nối đến cơ sở dữ liệu MongoDB được chỉ định trong tệp cấu hình. Sau khi kết nối thành công, chúng tôi đang xuất biến kết nối để sử dụng cho truy vấn
Tạo một tệp mới và đặt tên là người dùng. js trong thư mục mô hình
người dùng. js
const bcrypt = yêu cầu ["bcrypt"];
const { mongoConnection } = require["./connection"];
/**
* @thêm người dùng
*/
function addUser [ userData ] {
trả lại mới Lời hứa [async [resolve, reject] => {
thử {
// kiểm tra xem người dùng có tồn tại không
let checkUserData = await checkIfUserExists [{ email: dữ liệu người dùng. email }];
if [ checkUserData. dữ liệu && checkUserData. dữ liệu . độ dài > 0] {
// người dùng đã tồn tại, hãy gửi phản hồi
return giải quyết [{
lỗi . true,
tin nhắn . "Người dùng đã tồn tại với thông tin xác thực này. Vui lòng đăng nhập",
dữ liệu . [],
}];
}
// tạo hàm băm mật khẩu
let passwordHash = đang chờ bcrypt. băm[ dữ liệu người dùng. mật khẩu, 15];
Dữ liệu người dùng. mật khẩu = passwordHash ;
// thêm người dùng mới
mongoConnection
.bộ sưu tập["người dùng"]
.insertOne[ Dữ liệu người dùng , không đồng bộ [err, results] => {
nếu [ err ] {
bảng điều khiển. log[ err ];
ném mới Lỗi [err];
}
//trả lại dữ liệu
giải quyết [{
lỗi . sai,
dữ liệu . kết quả. ops[0],
}];
}];
} bắt [ e ] {
từ chối [ e ];
}
}];
}
/**
* @verifyUser
* @param {*} dữ liệu người dùng
*/
chức năng xác minh Người dùng [ Dữ liệu người dùng ] {
trả lại mới Lời hứa [async [resolve, reject] => {
thử {
hãy để userDatafromDb = đang chờ checkIfUserExists [{ email: dữ liệu người dùng. email }];
if [ userDatafromDb. dữ liệu && dữ liệu người dùng từ Db. dữ liệu . độ dài > 0] {
// người dùng đã tồn tại, hãy xác minh mật khẩu
hãy xác minh mật khẩu = đang chờ bcrypt. so sánh[
Dữ liệu người dùng. mật khẩu,
userDatafromDb. dữ liệu[0] . mật khẩu
];
nếu [. Xác minh mật khẩu ] {
// mật khẩu không khớp
return giải quyết [{
lỗi . true,
tin nhắn . "Email hoặc mật khẩu không hợp lệ",
dữ liệu . [],
}];
}
// xác minh mật khẩu
trả lại giải quyết [{ error: sai, dữ liệu . userDatatừDb. dữ liệu[0] }];
} else {
return giải quyết [{
lỗi . true,
tin nhắn .
"Không có người dùng nào có thông tin xác thực này. Vui lòng tạo một tài khoản mới. ",
dữ liệu . [],
}];
}
} bắt [ e ] {
bảng điều khiển. log[ e ];
từ chối [ e ];
}
}];
}
/**
* @checkIfUserExists
*/
hàm checkIfUserExists [ Dữ liệu người dùng ] {
trả lại mới Lời hứa [[resolve, reject] => {
thử {
// kiểm tra xem người dùng có tồn tại không
mongoConnection
.bộ sưu tập["người dùng"]
.tìm[{ email . dữ liệu người dùng. email }]
.toArray[[ err , results] => {
nếu [ err ] {
bảng điều khiển. log[ err ];
ném mới Lỗi [err];
}
giải quyết [{ lỗi . sai, dữ liệu . kết quả }];
}];
} bắt [ e ] {
từ chối [ e ];
}
}];
}
mô-đun. xuất = {
addUser . addUser ,
xác minh Người dùng . xác minh Người dùng ,
};
Trong mã được hiển thị ở trên, chúng tôi đang thêm một người dùng mới vào hệ thống của mình và xác minh người dùng đó bằng cách sử dụng kết hợp email và mật khẩu
Chúng tôi đang sử dụng mô-đun bcrypt để tạo mật khẩu băm và lưu trữ nó trong cơ sở dữ liệu và sau đó xác minh nó trong quá trình đăng nhập
Tiếp theo, chúng ta cần tạo một giao diện người dùng đơn giản để xác thực mã của mình. Tôi đã tạo một giao diện người dùng rất đơn giản. Tôi sẽ không hiển thị mã ở đây vì nó là mã HTML rất dài, nếu bạn muốn, bạn có thể xem mã ở đây
Chạy chương trình của chúng tôi
Chạy chương trình bằng lệnh sau
ứng dụng nút. js
Điều hướng trình duyệt của bạn đến localhost. 3000 để xem ứng dụng
Tạo người dùng mới
Đăng nhập bằng thông tin đăng nhập
Kiểm tra mục nhập trong cơ sở dữ liệu
trang hồ sơ người dùng
Cái gì tiếp theo?
Chúng tôi phải xây dựng một hệ thống đăng nhập và đăng ký người dùng đơn giản bằng Node, MongoDB và Redis. Trong kịch bản sản xuất, chúng tôi có thể cần phát triển tính năng xác minh người dùng, tính năng quên mật khẩu, tính năng xóa tài khoản, v.v. Các tính năng này có thể được xây dựng dựa trên cơ sở mã mà chúng tôi đã cùng nhau phát triển