https://expressjs.com/
Express JS
Fast, unopinionated, minimalist web framework for Node.js
Install
$ npm install express --savev PS C:\nodeproject> npm install express --save
https://expressjs.com/en/starter/hello-world.html
mysql
https://github.com/mysqljs/mysql
$ npm install mysql
PS C:\nodeproject>npm install mysql
cors
CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
https://www.npmjs.com/package/cors
PS C:\nodeproject>npm i cors
Passport
https://www.npmjs.com/package/passport
Passport is Express-compatible authentication middleware for Node.js.
npm i passport
express-session
https://www.npmjs.com/package/express-session
Create a session middleware with the given options.
npm install express-session
cookie-parser
https://www.npmjs.com/package/cookie-parser
Parse Cookie header and populate req.cookies with an object keyed by the cookie names.
npm install cookie-parser
bcrypt
https://www.npmjs.com/package/bcrypt
A library to help you hash passwords.
npm install bcrypt
passport-local
https://www.npmjs.com/package/passport-local
Passport strategy for authenticating with a username and password.
npm install passport-local
run PS C:\nodeproject> node index.js
index.js
//index.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport'); //npm install passport https://www.npmjs.com/package/passport
const expressSession = require('express-session'); //npm install express-session https://www.npmjs.com/package/express-session
const cookieParser = require('cookie-parser'); //npm install cookie-parser https://www.npmjs.com/package/cookie-parser
const bycrypt = require('bcrypt'); //npm install bcrypt https://github.com/kelektiv/node.bcrypt.js
const db = require('./db');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressSession({ secret: 'cairocoders-ednalan', resave: false, saveUninitialized: false }));
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));
app.use(cookieParser('cairocoders-ednalan'));
app.use(passport.initialize());
app.use(passport.session());
require('./passportConfig')(passport);
//routes
app.post('/register', (req, res) => {
const query = "INSERT INTO users (username, password) VALUES (?,?)";
const query2 = "SELECT * FROM users where username = ?";
db.query(query2, [req.body.username] ,async (err, rows) => {
if (err) {console.log(err);}
if (rows.length > 0) {res.send("User already exists");}
if (rows.length === 0) {
const hashedPassword = await bycrypt.hash(req.body.password, 10);
db.query(query, [req.body.username, hashedPassword], (err, rows) => {
if (err) {console.log(err);}
res.send("User created");
});
}
})
})
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) {console.log(err);}
if (!user) {res.send("User not found");}
if (user) {
req.login(user, (err) => {
if (err) {console.log(err);}
res.send("success");
console.log(user);
})
}
})(req, res, next);
})
app.get('/getUser', (req, res) => {
res.send(req.user);
console.log(req.user);
})
app.listen(3001, () => {console.log('Server started on port 3001')});
db.js
//db.js
const mysql = require("mysql");
const db = mysql.createPool({
socketPath: '/Applications/MAMP/tmp/mysql/mysql.sock',
connectionLimit: 10,
host: "localhost",
user: "root",
password: "root",
database: "nodeexpressDB"
});
// Ping database to check for common exception errors.
db.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.');
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.');
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.');
}
}
if (connection) connection.release();
return;
});
module.exports = db;
passportConfig.js
//passportConfig.js
const db = require('./db');
const bcrypt = require('bcrypt');
const localStrategy = require('passport-local').Strategy; //npm install passport-local https://www.npmjs.com/package/passport-local
module.exports = function(passport) {
passport.use(
new localStrategy((username, password, done) => {
const query = "SELECT * FROM users where username = ?";
db.query(query, [username] ,(err, rows) => {
if(err)throw err;
if(rows.length === 0) {
return done(null, false);
}
bcrypt.compare(password, rows[0].password, (err, result) => {
if (err) throw err;
if (result === true) {
return done(null, rows[0]);
}
else {
return done(null, false);
}
})
})
}))
passport.serializeUser((user, done) => {
done(null, user.id);
})
passport.deserializeUser((id, done) => {
const query = "SELECT * FROM users where id = ?";
db.query(query, [id] ,(err, rows) => {
if(err)throw err;
const userInfo = {
id: rows[0].id,
username: rows[0].username
}
done(null, userInfo);
})
})
}
Next.js Install requirements
npm install axios
https://www.npmjs.com/package/axios
app\page.js
//
export default function Home() {
return (
<div className="w-screen py-20 flex justify-center flex-col items-center">
<div className="flex items-center justify-between gap-1 mb-5">
<h1 className="text-4xl font-bold">Next.js 14 Node Express Login Register with Passportjs | Mysql</h1>
</div>
Homepage
</div>
);
}
app\users\login\page.jsx
//app\users\login\page.jsx
"use client";
import { useState } from 'react'
import axios from 'axios'
import Link from 'next/link';
import { useRouter } from 'next/navigation';
export default function Home() {
const [loginUsername, setLoginUsername] = useState('')
const [ loginPassword, setLoginPassword ] = useState('')
const[message, setMessage]= useState('');
const router = useRouter();
const login = () => {
axios({
method: 'post',
data: {
username: loginUsername,
password: loginPassword
},
withCredentials: true,
url: 'http://localhost:3001/login'
})
.then(res => {
console.log(res)
if (res.data == "success") {
router.push('/users/profile')
}else {
setMessage(res.data);
}
})
.catch(err => {console.log(err)})
}
return (
<div className="flex justify-center relative">
<div className="mx-auto max-w-lg px-6 lg:px-8 absolute py-20">
<h1 className="text-center text-3xl">Login </h1>
<div className="rounded-2xl bg-white shadow-xl">
<div className="lg:p-11 p-7 mx-auto">
<div className="mb-11">
<h1 className="text-gray-900 text-center font-manrope text-3xl font-bold leading-10 mb-2">Welcome Back</h1>
<p className="text-gray-500 text-center text-base font-medium leading-6">Let’s get started with your 30 days free trail</p>
</div>
<input type="text" className="w-full h-12 text-gray-900 placeholder:text-gray-400 text-lg font-normal leading-7 rounded-full border-gray-300 border shadow-sm focus:outline-none px-4 mb-6"
placeholder="Username"
name="username"
onChange={e => setLoginUsername(e.target.value )}
/>
<input type="text" className="w-full h-12 text-gray-900 placeholder:text-gray-400 text-lg font-normal leading-7 rounded-full border-gray-300 border shadow-sm focus:outline-none px-4 mb-1"
placeholder="Password"
name="password"
onChange={e => setLoginPassword(e.target.value )}
/>
<Link href="#" className="flex justify-end mb-6">
<span className="text-indigo-600 text-right text-base font-normal leading-6">Forgot Password?</span>
</Link>
<button onClick={login} className="w-full h-12 text-white text-center text-base font-semibold leading-6 rounded-full hover:bg-indigo-800 transition-all duration-700 bg-indigo-600 shadow-sm mb-11">Login</button>
<p className="text-red-700"><b>{ message }</b></p>
<Link href="/users/register" className="flex justify-center text-gray-900 text-base font-medium leading-6"> Don’t have an account? <span className="text-indigo-600 font-semibold pl-3"> Sign Up</span>
</Link>
</div>
</div>
</div>
</div>
);
}
app\users\register\page.jsx
//app\users\register\page.jsx
"use client";
import { useState } from 'react'
import axios from 'axios'
import Link from 'next/link';
import { useRouter } from 'next/navigation';
export default function Home() {
const [registerUsername, setRegisterUsername] = useState('')
const [ registerPassword, setRegisterPassword ] = useState('')
const[message, setMessage]= useState('');
const router = useRouter();
const register = () => {
axios({
method: 'post',
data: {
username: registerUsername,
password: registerPassword
},
withCredentials: true,
url: 'http://localhost:3001/register'
})
.then(res => {
console.log(res)
if (res.data == "User already exists") {
setMessage(res.data);
}else {
router.push('/')
}
})
.catch(err => {console.log(err)})
}
return (
<div className="flex justify-center relative">
<div className="mx-auto max-w-lg px-6 lg:px-8 absolute py-20">
<h1 className="text-center text-3xl">Register </h1>
<div className="rounded-2xl bg-white shadow-xl">
<div className="lg:p-11 p-7 mx-auto">
<div className="mb-11">
<h1 className="text-gray-900 text-center font-manrope text-3xl font-bold leading-10 mb-2">Create Account</h1>
<p className="text-gray-500 text-center text-base font-medium leading-6">Get started with your free account</p>
</div>
<input type="text" className="w-full h-12 text-gray-900 placeholder:text-gray-400 text-lg font-normal leading-7 rounded-full border-gray-300 border shadow-sm focus:outline-none px-4 mb-6"
placeholder="Username"
name="username"
onChange={e => setRegisterUsername(e.target.value )}
/>
<input type="text" className="w-full h-12 text-gray-900 placeholder:text-gray-400 text-lg font-normal leading-7 rounded-full border-gray-300 border shadow-sm focus:outline-none px-4 mb-1"
placeholder="Password"
name="password"
onChange={e => setRegisterPassword(e.target.value)}
/>
<button onClick={register} className="w-full h-12 text-white text-center text-base font-semibold leading-6 rounded-full hover:bg-indigo-800 transition-all duration-700 bg-indigo-600 shadow-sm mb-11">Submit</button>
<p className="text-red-700"><b>{ message }</b></p>
<Link href="/users/login" className="flex justify-center text-gray-900 text-base font-medium leading-6"> have an account? <span className="text-indigo-600 font-semibold pl-3"> Login</span>
</Link>
</div>
</div>
</div>
</div>
);
}
app\users\profile\page.jsx
//app\users\profile\page.jsx
"use client";
import { useState } from 'react'
import axios from 'axios'
export default function Home() {
const [ user, setUser ] = useState(null)
const getUser = () => {
axios({
method: 'get',
withCredentials: true,
url: 'http://localhost:3001/getUser'
}).then(res => {setUser(res.data.username)}).catch(err => {console.log(err)})
}
return (
<div className="flex justify-center relative">
<div className="mx-auto max-w-lg px-6 lg:px-8 absolute py-20">
<h1 className="text-center text-3xl">Profile </h1>
<div className="rounded-2xl bg-white shadow-xl">
<button onClick={getUser} className="w-full h-12 text-white text-center text-base font-semibold leading-6 rounded-full hover:bg-indigo-800 transition-all duration-700 bg-indigo-600 shadow-sm mb-11">Submit</button>
{user ? <h1>{user}</h1> : null}
</div>
</div>
</div>
);
}
run C:\nextjs>npm run dev
