当前位置:网站首页>Node. Js: express + MySQL realizes registration, login and identity authentication
Node. Js: express + MySQL realizes registration, login and identity authentication
2022-07-06 20:03:00 【Players with hair loss type】
Some content in this article is like field verification , The project structure and other parts are written in another article :Node.js: express + MySQL Use _ Blog of players with hair loss type -CSDN Blog
One , Implement registration
1, To register, you need to write the account and password of the new user into the database , The account can be written directly into the database , But passwords are generally not stored directly in the database , The password will be encrypted and stored in the database , It can improve the security of the account .
2, When logging in, encrypt the password in the same way , Compare with the password stored in the database , If it is the same, the login is successful .
3, Realization
(1), First create a table in the database to store information , The name of the table I created is user_login
(2), Password encryption uses a package bcryptjs , This package can encrypt passwords , use npm Install it into the project .
(3), Directory structure , In the routing module , Processing function module , Create a new file under the field verification module , Used to complete this part .
app.js
// introduce express
const express = require("express");
// Create an instance object of the server
const app = express();
// Packages that introduce validation rules , When defining middleware with error level
const joi = require("joi");
// Configure middleware for parsing form data Built in middleware , Can only parse application/x-www-form-urlencoded Formatted data
app.use(express.urlencoded({ extended: false }));
// encapsulation res.send() , Must be encapsulated before routing
/**
* Whether it is to output correct data or wrong information , I need to write so many things every time
* res.send({ state: 0, message: " The query is successful ", data: result })
* There is no need to write so much after encapsulation
*/
app.use((req, res, next) => {
// Define an output function
res.output = function (err, status = 1, data) {
res.send({
status,
message: err instanceof Error ? err.message : err,
data,
});
};
next();
});
// Import and use login , Registered routing module
const loginRouter = require("./router/login");
app.use(loginRouter);
// Import and use the routing module
const inforRouter = require("./router/userInfor");
app.use(inforRouter);
// Call the error level middleware under all routes
app.use((err, req, res, next) => {
// Error caused by validation failure
if (err instanceof joi.ValidationError) return res.output(err);
// // Error after identity authentication failure
// if(err.name === 'UnauthorizedError') return res.cc(' Authentication failed !')
// Unknown error
res.output(err);
next();
});
// Start the server
app.listen(3007, () => {
console.log("Server running at http://127.0.0.1:3007");
});
because app.js It's the entry file for the whole project , All routes should be imported and used in this file .
router Under folder login.js file
const express = require("express");
const router = express.Router();
// Import the middle price of the verification rule
const expressJoi = require("@escook/express-joi");
// Introduce rules
const { login_rules } = require("../schema/login");
// Introduce a handler
const login_handler = require("../router_handler/login");
// register
router.post("/register", expressJoi(login_rules), login_handler.userRegister);
// Export route
module.exports = router;
As in the previous article , Register routes in this file , And from router_handler Import processing function in , Import middleware and rules of verification rules , Finally, export the route , stay app.js Use... In the document .
router_handler Under folder login.js file ( Processing function )
// Import database module
const db = require("../db/index");
// Introduce a package that encrypts passwords
const bcryptjs = require("bcryptjs");
// Register the handler and Export
exports.userRegister = (req, res) => {
// First get the value passed from the client
let { username, password } = req.body;
/**
* The user name is unique when registering , It can't be the same as other people's user names
* Before writing information to the database , First check whether the user name is occupied
*/
// Query whether there is the same user name
const sql = "select username from user_login where username=?";
// Perform a search sql sentence
db.query(sql, username, (err, results) => {
// sql Statement execution failed
if (err) return res.output(err);
// Successful implementation , If there's data , It means that there is the same user name
if (results.length === 1) return res.output(" User name occupied ");
// Successful implementation , The user name is not occupied
console.log(' Before encryption ', password);
// Encrypt password , The second parameter can improve the security of passwords , A few will do
password = bcryptjs.hashSync(password, 10);
console.log(' After encryption ', password);
// Define a new statement , Add user
const sqlStr = "insert into user_login set ?";
// Execution increase sql sentence
db.query(sqlStr, { username, password }, (err, results) => {
// perform sql Statement failure
if (err) return res.output(err);
// perform sql Statement success But the number of affected lines is not 1
if (results.affectedRows !== 1) return res.output(" User registration failed !");
// Successful implementation , The number of affected lines is 1
res.output(" Registered successfully !");
});
});
};
(1), First get the user name and password to be registered from the client , When deconstructing user names and passwords, use let, Because the password needs to be encrypted in the following operations , Changed variables . use const, It's OK to redefine a value .
(2), There are three steps in the registration process , The first step is to query the user name in the database for the same value , User names cannot be the same , If there is the same, the return user name is occupied .
(3), If you do not have the same user name and password , You can use , Encrypt the password set by the user , Use bcryptjs Package encryption . Use hashSync() Method , The first parameter is the original password , The second parameter can improve the security of passwords , It's a number .
(4), After encryption, you can check the encrypted password at the terminal output , Data can be stored in a database , Use insert sentence , If the database statement is executed successfully , But the number of affected lines is not 1, It also belongs to failure .
schema Under folder login.js file ( Validation rules , stay router In the catalog login.js Use... In the document )
// Import the package of verification rules
const joi = require("joi");
// Set the rules
const username = joi.string().alphanum().min(1).max(16).required();
const password = joi.string().pattern(/^[\S]{6,12}$/).required();
// Export rules
exports.login_rules = {
body: {
username,
password,
},
};
Use it after writing postman Test it , First test whether the verification rule can be used , Input a wrong , The wrong password does not conform to the rule .
Then change the password to match the verification :
Registered successfully , Check the password before and after encryption on the terminal , There is also a new piece of data in the database .
Then click again send, This time, there is data in the database at the time of registration , And the user name is occupied .
Report errors , User name occupied .
Two , To realize the login
To realize the login , A bag will be used jsonwebtoken , This package can generate token.
File structure :
This time, a global configuration file is added ,config.js, This file is set to generate token The key of the encryption method when , and token Duration of , The key and time can also be written directly in the file , But encryption requires , Decryption also requires , For the convenience of pulling him out . The key can be set at will .
config.js file
// Global profile
module.exports = {
/**
* Set up token The key used for encryption and decryption
*/
jwtSecretKey: 'c^_^h',
/**
* Set up token The validity of the
*/
expiresIn: '10h',
}
router Under folder login.js file ( Configure the route in this file )
const express = require("express");
const router = express.Router();
// Import the middle price of the verification rule
const expressJoi = require("@escook/express-joi");
// Introduce rules
const { login_rules } = require("../schema/login");
// Introduce a handler
const login_handler = require("../router_handler/login");
// register
router.post("/register", expressJoi(login_rules), login_handler.userRegister);
// Sign in , The same rules apply to fields when logging in
router.post("/login", expressJoi(login_rules), login_handler.userLogin);
// Export route
module.exports = router;
User name and password are used for registration and login , The rules of these two are the same .
router_handler Under folder login.js file ( Login handler )
// Import database module
const db = require("../db/index");
// Introduce a package that encrypts passwords
const bcryptjs = require("bcryptjs");
// Import build token My bag
const jwt = require("jsonwebtoken");
// Import global configuration file , Ciphertext
const config = require("../config");
// Register the handler
exports.userRegister = (req, res) => {
// First get the value passed from the client
let { username, password } = req.body;
/**
* The user name is unique when registering , It can't be the same as other people's user names
* Before writing information to the database , First check whether the user name is occupied
*/
// Query whether there is the same user name
const sql = "select username from user_login where username=?";
// Perform a search sql sentence
db.query(sql, username, (err, results) => {
// sql Statement execution failed
if (err) return res.output(err);
// Successful implementation , If there's data , It means that there is the same user name
if (results.length === 1) return res.output(" User name occupied ");
// Successful implementation , The user name is not occupied
// Define a new statement , Add user
const sqlStr = "insert into user_login set ?";
console.log(" Before encryption ", password);
// Encrypt password , The second parameter can improve the security of passwords , A few will do
password = bcryptjs.hashSync(password, 10);
console.log(" After encryption ", password);
// Execution increase sql sentence
db.query(sqlStr, { username, password }, (err, results) => {
// perform sql Statement failure
if (err) return res.output(err);
// perform sql Statement success But the number of affected lines is not 1
if (results.affectedRows !== 1) return res.output(" User registration failed !");
// Successful implementation , The number of affected lines is 1
res.output(" Registered successfully !");
});
});
};
// Login handler
exports.userLogin = (req, res) => {
// Receive form data
const { username, password } = req.body;
// First, check whether the user name is in the database , Definition sql sentence
const sql = "select * from user_login where username=?";
// Execute statement
db.query(sql, username, (err, results) => {
if (err) return res.output(err);
// Statement executed successfully , But there is no corresponding username
if (results.length !== 1) return res.output(" Login failed ");
// Statement executed successfully , There are also corresponding username
// Compare passwords
// The front is the password of the client , Then there is the encrypted password stored in the database
const compareResult = bcryptjs.compareSync(password, results[0].password);
// Returns the true or false
if (!compareResult) {
return res.output(" Wrong password , Login failed !");
}
// The password comparison is correct , Generate... On the server side token Field
// Get user information , Remove the password , Generate token
const user = { ...results[0], password: "" };
// Encrypt the user's information , Generate token character string , Parameters 2 And parameters 3 You can write directly , You can also take it out
const tokenStr = jwt.sign(user, config.jwtSecretKey, {
expiresIn: config.expiresIn,
});
// call res.send take token Respond to clients
res.output(" Login successful ", 0, "Bearer " + tokenStr);
});
};
(1), First receive the user name and password from the client , Then look for the corresponding user name in the database , without , The user name is wrong , Login failed .
(2), If there is a corresponding user name , Compare whether the passwords are the same , Compare the password or use bcryptjs package , Use it compareSync() Method , This method has two parameters , The first is the password passed from the client , The second parameter is to store the encrypted password in the database , According to the result, it will return true or false, If it's not the same , Login failed .
(3), If the password is the same, login succeeds , To generate token Back to the client , be used jsonwebtoken package ,sign() Method , It generates token, User information will generally remove the password . The second parameter is the key , The third parameter is time , How long is the validity period , The final will be token Return to client .
(4),token The client cannot directly use , It needs to be preceded by 'Bearer ', When returning, add this , The front end can be used directly .
Login successful .
3、 ... and , Login inside and login outside
The functions of the project are divided into login and login functions , For example, a blog system , When not logged in , You can check the articles inside , But only after login , To publish an article .
The interface in the login should be submitted in the request header when requesting token, Authentication . Only in app.js There are modifications in , Other documents remain unchanged .
app.js
// introduce express
const express = require("express");
// Create an instance object of the server
const app = express();
// Packages that introduce validation rules , When defining middleware with error level
const joi = require("joi");
// Configure middleware for parsing form data Built in middleware , Can only parse application/x-www-form-urlencoded Formatted data
app.use(express.urlencoded({ extended: false }));
// encapsulation res.send() , Must be encapsulated before routing
/**
* Whether it is to output correct data or wrong information , I need to write so many things every time
* res.send({ state: 0, message: " The query is successful ", data: result })
* There is no need to write so much after encapsulation
*/
app.use((req, res, next) => {
// Define an output function
res.output = function (err, status = 1, data) {
res.send({
status,
message: err instanceof Error ? err.message : err,
data,
});
};
next();
});
// Configure resolution before routing token Middleware
const { expressjwt: jwt } = require("express-jwt");
// analysis token need token The key of
const config = require("./config");
// Define middleware , Which key resolution is needed ,.unless Specify which interfaces do not need to be token Identity Authentication
app.use(
jwt({ secret: config.jwtSecretKey, algorithms: ["HS256"] }).unless({
path: [/^\/api/],
})
);
// Import and use login , Registered routing module
const loginRouter = require("./router/login");
app.use("/api", loginRouter);
// Import and use the routing module
const inforRouter = require("./router/userInfor");
app.use(inforRouter);
// Call the error level middleware under all routes
app.use((err, req, res, next) => {
// Error caused by validation failure
if (err instanceof joi.ValidationError) return res.output(err);
// Unknown error
res.output(err);
next();
});
// Start the server
app.listen(3007, () => {
console.log("Server running at http://127.0.0.1:3007");
});
(1), In the request header token, The interface request should be parsed token, analysis token A package is required express-jwt , And generate token The same key .
(2), There is no definition of parsing token When using the middleware of , Request at this time, all routes still do not need token Of , After defining , All routes need token 了 .unless() You can specify which routes do not need token.algorithms attribute , Set up jwt The algorithm of , You can see express-jwt Documents .
(3),app.use("/api", loginRouter); When using routing , Add in front ‘/api', On request , You also need to add '/api', There is no need to submit when logging in and registering token.
Not submitted token, Report errors .
Send up token, The query is successful .
Finally, sort out the packages used in the whole process :
express: frame
mysql: database
@escook/express-joi: Automatically validate form data
joi: Rules of the field
bcryptjs: Encrypt the password
jsonwebtoken: Generate token
express-jwt: Please send token Post analysis token
边栏推荐
- 深入浅出,面试突击版
- 夏志刚介绍
- js获取浏览器系统语言
- Learn to explore - use pseudo elements to clear the high collapse caused by floating elements
- Vmware虚拟机无法打开内核设备“\\.\Global\vmx86“的解决方法
- LeetCode_ Double pointer_ Medium_ 61. rotating linked list
- Chic Lang: attributeerror: partially initialized module 'CV2' has no attribute 'GAPI_ wip_ gst_ GStreamerPipe
- HMS Core 机器学习服务打造同传翻译新“声”态,AI让国际交流更顺畅
- Tencent Android interview must ask, 10 years of Android development experience
- Test Li hi
猜你喜欢
An East SMS login resurrection installation and deployment tutorial
激进技术派 vs 项目保守派的微服务架构之争
In simple terms, interview surprise Edition
腾讯字节阿里小米京东大厂Offer拿到手软,老师讲的真棒
[infrastructure] deployment and configuration of Flink / Flink CDC (MySQL / es)
夏志刚介绍
Hudi vs Delta vs Iceberg
A5000 vGPU显示模式切换
Example of applying fonts to flutter
《数字经济全景白皮书》保险数字化篇 重磅发布
随机推荐
腾讯架构师首发,2022Android面试笔试总结
Introduction to enterprise lean management system
系统与应用监控的思路和方法
Database specific interpretation of paradigm
A5000 vGPU显示模式切换
Crawler (14) - scrape redis distributed crawler (1) | detailed explanation
Vmware虚拟机无法打开内核设备“\\.\Global\vmx86“的解决方法
企业精益管理体系介绍
社招面试心得,2022最新Android高频精选面试题分享
深度剖析原理,看完这一篇就够了
句号压缩过滤器
An East SMS login resurrection installation and deployment tutorial
Social recruitment interview experience, 2022 latest Android high-frequency selected interview questions sharing
js获取浏览器系统语言
121. The best time to buy and sell stocks
技术分享 | 抓包分析 TCP 协议
精彩编码 【进制转换】
[translation] Digital insider. Selection process of kubecon + cloudnativecon in Europe in 2022
Configuration and simple usage of the EXE backdoor generation tool quasar
Tencent Android development interview, basic knowledge of Android Development