bcrypt password encryption
In practical applications, it is not safe to store user passwords directly in plaintext. Here is how to use password parsing and parsing
- Installing the bcrypt module
yarn add bcrypt
- Encryption and parsing function
You need to encapsulate promise to avoid errors caused by asynchrony
exports.hash = (myPlaintextPassword) => { return new Promise((resolve, reject) => { //The second parameter is salt bcrypt.hash(myPlaintextPassword, 10, function (err, hash) { if(err){ reject(err) }else{ //If successful, the encrypted hash value will be returned resolve(hash) } }) }) } exports.compare=(myPlaintextPassword,hash)=>{ return new Promise((resolve,reject)=>{ bcrypt.compare(myPlaintextPassword,hash,(err,result)=>{ if(err){ reject(err) }else{ resolve(result) } }) }) }
- Encrypt the returned password in the registration interface
const signup = async (req, res, next) => { res.set('content-type', 'application/json;charset=utf-8') const { username, password } = req.body //Password encryption const bcryptPaaword = await hash(password) const isexit = await UserModel.findOne({ username }) if (isexit) { res.render('fail', { data: 'User name already exists!' }) } else { const result = await UserModel.signup({ username, password: bcryptPaaword }) res.render('suc', { data: JSON.stringify( { msg: 'login was successful' } ) }) } }
The method of parsing the login interface will be described in the authentication below
Cookie session authentication
The server generates a session from the user name or other information, and compares the information for authentication each time the user requests.
- First install the cookie session third-party package
yarn add cookie-session
- On app JS
var cookieSession = require('cookie-session') app.use(cookieSession({ name: 'session', keys: ['key1', 'key2'] }))
There is a hole in this area. The registration here needs to be above the route registration, otherwise an error will be reported.
- After successful registration, the session is stored in the code after each successful login.
const login = async (req, res, next) => { res.set('content-type', 'application/json;charset=utf-8') const { username, password } = req.body const result = await UserModel.findOne({ username }) if (result) { const { password: hashPassword } = result //Compare passwords after hash encryption const isTrue = await compare(password, hashPassword) if (isTrue) { req.session.username=username res.render('suc', { data: JSON.stringify({ msg: 'Login successful', username, token }) }) } else { res.render('fail', { data: JSON.stringify({ msg: 'Wrong user name or password' }) }) } } else { res.render('fail', { data: JSON.stringify({ msg: 'Wrong user name or password' }) }) } }
- Create authentication Middleware
Create a new auth JS, let the request to be authenticated go through auth authentication before each request. If the previously stored username exists, the authentication passes. Otherwise, return the information to let the user log in again
const auth=(req,res,next)=>{ if(req.session.username){ //Release, continue request next() }else{ res.render('auth', { data: JSON.stringify({ msg: 'No permission!Please login!' }) }) } } //In routes, the auth request is passed before the list request router.get('/list', auth,list)
Using cookie session for authentication is rarely used now. The reason is that under multi-user use, continuously storing sessions in the server will cause excessive pressure on the server. At present, the more popular authentication method is token
Token authentication
Token authentication is to generate a token and return it to the front end after the user logs in successfully. After that, every request from the front end needs to carry a token. If it passes the verification, the request can continue. The token does not have to be stored in the server, but is stored by the front end through the browser storage technology.
- Install the JSON webtokn package
yarn add jsonwebtoken
The encryption of token includes symmetric encryption and asymmetric encryption.
In short, symmetric encryption is actually the same key used for encryption and decryption, while asymmetric encryption is inconsistent. For this asymmetric encryption, we use public key and private key.
- Install openssl
Download address: http://slproweb.com/products/Win32OpenSSL.html
The installation and setting environment variables of this piece will not be repeated. Baidu or view this article by yourself
https://blog.csdn.net/qq_39081974/article/details/81059022 - Create the keys folder and execute the following commands to create the public key and private key
utilize openssl Generate public and private keys Generate public key: openssl genrsa -out rsa_private_key.pem 1024 Generate private key: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
- Create and parse token functions
exports.createToken=(username)=>{ //Read the private key and generate a token according to the user name and private key. An algorithm needs to be passed in when generating the private key const private=fs.readFileSync(path.join(__dirname,'../keys/rsa_private_key.pem')) let token=jwt.sign({username},private,{ algorithm: 'RS256' }) return token } exports.verifyToken=(token)=>{ //Read the public key and parse the token according to the token and the public key. There is no need to pass in the algorithm const public=fs.readFileSync(path.join(__dirname,'../keys/rsa_public_key.pem')) console.log(jwt.verify(token,public)); return jwt.verify(token,public) }
- Authentication in auth
Like the above cookie session authentication, auth requests need to be filtered
Get the token in the request header for parsing. If there is an error, it will directly return no permission
const auth = (req, res, next) => { const token = req.headers.token try { verifyToken(token) next() } catch (error) { res.render('auth', { data: JSON.stringify({ msg: 'No permission!Please login!' }) }) } }