Home >Web Front-end >JS Tutorial >Using Passport With Sequelize and MySQL

Using Passport With Sequelize and MySQL

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2025-03-11 11:04:09765browse

Sequelize is a promise-based Node.js ORM. It can be used with PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL. In this tutorial, we will be implementing authentication for users of a web app. And we will use Passport, the popular authentication middleware for Node, together with Sequelize and MySQL, to implement user registration and login.

Getting Started

Make sure you have the following installed on your machine:

  • Node
  • MySQL

For this tutorial, we will be using Node.js and the Express framework, so we go ahead and start installing what we need.

1. Generate a package.json File

Create a directory for your app. Inside this directory, run this from your terminal or command prompt:

 npm init<br>

This initializes the npm dependency manager. This will present a series of prompts which we'll quickly go through.

  • Type the name of your app without spaces for name.
  • Press Enter to use the default version.
  • Enter a description or leave it blank.
  • For entry point, type server.js.
  • You can press Enter to accept the default for the rest of the prompts.

2. Install Dependencies

The major dependencies for this tutorial are:

  • Express
  • Sequelize
  • MySQL
  • Passport
  • Passport Local Strategy
  • Express Session
  • Bcryptjs
  • Express Handlebars for the views

To install them, from your terminal or command prompt, run the following one after another.

npm install express --save<br>npm install sequelize --save<br>npm install sequelize --save<br>npm install mysql --save<br>npm install passport --save<br>npm install passport-local --save<br>npm install express-session --save<br>npm install bcryptjs --save<br>npm install express-handlebars --save<br>npm install mysql2 --save<br>

If you're using Git for this project, create a express. We then initialize express and then assign it to the variable passport module and the passport and models.sequelize sync function. Run this to see if all is well:

node server.js<br>

If you get the message "Site is live. Nice! Database looks fine", then you have set up Sequelize successfully.

If not, please go carefully over the steps above and try to debug the issue with help.

Step 2: Create the User Model

The next thing we are going to do is create the user model, which is basically the user table. This will contain basic user information.

In our models folder, we create a file and name it user.js. The full path for this file should be app/models/user.js.

Open the user.js file and add the following code:

module.exports = function(sequelize, Sequelize) {<br>    var User = sequelize.define('user', {<br>        id: {<br>            autoIncrement: true,<br>            primaryKey: true,<br>            type: Sequelize.INTEGER<br>        },<br>        firstname: {<br>            type: Sequelize.STRING,<br>            notEmpty: true<br>        },<br>        lastname: {<br>            type: Sequelize.STRING,<br>            notEmpty: true<br>        },<br>        username: {<br>            type: Sequelize.TEXT<br>        },<br>        about: {<br>            type: Sequelize.TEXT<br>        },<br>        email: {<br>            type: Sequelize.STRING,<br>            validate: {<br>                isEmail: true<br>            }<br>        },<br>        password: {<br>            type: Sequelize.STRING,<br>            allowNull: false<br>        },<br>        last_login: {<br>            type: Sequelize.DATE<br>        },<br>        status: {<br>            type: Sequelize.ENUM('active', 'inactive'),<br>            defaultValue: 'active'<br>        }<br>    });<br>    return User;<br>}<br>

Now run:

node server.js<br>

You should see the familiar "Site is live. Nice! Database looks fine" message. This means that our Sequelize models have been synced successfully, and if you check your database, you should see a users table with the columns specified.

Step 3: Set Up Views

In this section, we will set up the views for the client side. First, let's create the view for signup and wire it up.

The first thing to do is import the authController file and define the signup route.

var authController = require('../controllers/authController.js');<br>module.exports = function(app) {<br>    app.get('/signup', authController.signup);<br>};<br>

Now, we'll import this route in our server.js and pass the app as an argument. In server.js, after the models import, add these lines:

//Routes<br>var authRoute = require('./app/routes/auth.js')(app);<br>

Run this:

node server.js<br>

Now, visit http://localhost:5000/signup, and you will see the signup form.

Using Passport With Sequelize and MySQL

Let's repeat the steps for the sign-in form. As before, we'll create a file named signin.hbs in our views folder and paste the following HTML code in it:

<br><br><br>    <title>Sign in Layout</title><br>    <link rel="stylesheet" href="/styles.css"><br><br><br>    <h2>Passport With Sequelize and MySQL</h2><br>    









Then, add a controller for the sign-in in app/controllers/authcontroller.js.

exports.signin = function(req, res) {<br>    res.render('signin');<br>};<br>

Then, in app/routes/auth.js, we add a route for sign-in like this:

bcryptjs, which we need to secure passwords.

module.exports block like this:

module.exports = function(passport, user) {<br>}<br>

Inside this block, we initialize the LocalStrategy like this:

passport.use('local-signup', new LocalStrategy(<br>    {<br>        usernameField: 'email',<br>        passwordField: 'password',<br>        passReqToCallback: true // allows us to pass back the entire request to the callback<br>    },<br>))<br>

Now we have declared what request fields our passwordField (passport variables) are.

The last variable User, we check to see if the user already exists, and if not, we add them.

User.findOne({<br>    where: {<br>        email: email<br>    }<br>}).then(function(user) {<br>    if (user)<br>    {<br>        return done(null, false, {<br>            message: 'That email is already taken'<br>        });<br>    } else<br>    {<br>        var userPassword = generateHash(password);<br>        var data =<br>            {<br>                email: email,<br>                password: userPassword,<br>                firstname: req.body.firstname,<br>                lastname: req.body.lastname<br>            };<br>        User.create(data).then(function(newUser, created) {<br>            if (!newUser) {<br>                return done(null, false);<br>            }<br>            if (newUser) {<br>                return done(null, newUser);<br>            }<br>        });<br>    }<br>});<br>

req.body object, which contains the input from our signup form.

Your routes import.

//load passport strategies<br>require('./app/config/passport/passport.js')(passport, models.user);<br>

Your server.js should now look like this:

var express = require('express');
var app = express();
var passport = require('passport');
var session = require('express-session');
var env = require('dotenv').config();
var exphbs = require('express-handlebars');
app.use(express.urlencoded({
extended: true
})
);
app.use(express.json());
// For Passport
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
//For Handlebars
app.set('views', './app/views');
app.engine('hbs', exphbs.engine({
extname: '.hbs',
defaultLayout: false,
layoutsDir: "views/layouts/"
}));
app.set('view engine', '.hbs');
app.get('/', function(req, res) {
res.send('Welcome to Passport with Sequelize');
});
//Models
var models = require("./app/models");
//Routes<br>var authRoute = require('./app/routes/auth.js')(app);<br>//load passport strategies<br>require('./app/config/passport/passport.js')(passport, models.user);<br>//Sync Database
models.sequelize.sync().then(function() {
console.log('Nice! Database looks fine');
}).catch(function(err) {
console.log(err, "Something went wrong with the Database Update!");
});
app.listen(5000, function(err) {
if (!err)
console.log("Site is live");
else console.log(err);
});

Now we will actually apply the strategy to our /signup route. Here's how we do that:

First, we go to app/routes/auth.js and add a route for posting to signup like this.

app.post('/signup', passport.authenticate('local-signup', {<br>        successRedirect: '/dashboard',<br>        failureRedirect: '/signup'<br>    }<br>));<br>

Since we need passport, we need to pass it to this method. We can import passport in this script or pass it from server.js. Let's do the latter.

Modify the function exported in this file app/routes/auth.js to have passport as a parameter. The code in app/routes/auth.js should look like this after your modification.

var authController = require('../controllers/authcontroller.js');<br>module.exports = function(app, passport) {<br>    app.get('/signup', authController.signup);<br>    app.get('/signin', authController.signin);<br>    app.post('/signup', passport.authenticate('local-signup', {<br>            successRedirect: '/dashboard',<br>            failureRedirect: '/signup'<br>        }<br>    ));<br>};<br>

Then, in server.js, we modify the module.exports block, below all the other lines of code.

function isLoggedIn(req, res, next) {<br>    if (req.isAuthenticated())<br>    <br>        return next();<br>        <br>    res.redirect('/signin');<br>}<br>

Then we modify the dashboard route handler to look like this:

app.get('/dashboard',isLoggedIn, authController.dashboard);<br>

Now, when you run the app again and try to visit the dashboard page and you are not logged in, you should be redirected to the sign-in page.

Whew! It is time to implement the final part: the sign-in.

First, we'll add a new local strategy for sign-in in app/config/passport/passport.js.

//LOCAL SIGNIN<br>passport.use('local-signin', new LocalStrategy(<br>    {<br>        // by default, local strategy uses username and password, we will override with email<br>        usernameField: 'email',<br>        passwordField: 'password',<br>        passReqToCallback: true // allows us to pass back the entire request to the callback<br>    },<br>    function(req, email, password, done) {<br>        var User = user;<br>        var isValidPassword = function(userpass, password) {<br>            return bCrypt.compareSync(password, userpass);<br>        }<br>        User.findOne({<br>            where: {<br>                email: email<br>            }<br>        }).then(function(user) {<br>            if (!user) {<br>                return done(null, false, {<br>                    message: 'Email does not exist'<br>                });<br>            }<br>            if (!isValidPassword(user.password, password)) {<br>                return done(null, false, {<br>                    message: 'Incorrect password.'<br>                });<br>            }<br>            var userinfo = user.get();<br>            return done(null, userinfo);<br>        }).catch(function(err) {<br>            console.log("Error:", err);<br>            return done(null, false, {<br>                message: 'Something went wrong with your Signin'<br>            });<br>        });<br>    }<br>));<br>

In this strategy, the isValidPassword function compares the password entered with the bCrypt comparison method since we stored our password with bcrypt. If the details are correct, our user will be signed in.

Now, go to routes/auth.js and add the route for posting to /signin.

app.post('/signin', passport.authenticate('local-signin', {<br>        successRedirect: '/dashboard',<br>        failureRedirect: '/signin'<br>    }<br>));<br>

Your routes/auth.js should look like this when you're done.

var authController = require('../controllers/authcontroller.js');<br>module.exports = function(app, passport) {<br>    app.get('/signup', authController.signup);<br>    app.get('/signin', authController.signin);<br>    app.post('/signup', passport.authenticate('local-signup', {<br>            successRedirect: '/dashboard',<br>            failureRedirect: '/signup'<br>        }<br>    ));<br>    app.get('/dashboard', isLoggedIn, authController.dashboard);<br>    app.get('/logout', authController.logout);<br>    app.post('/signin', passport.authenticate('local-signin', {<br>            successRedirect: '/dashboard',<br>            failureRedirect: '/signin'<br>        }<br>    ));<br>    function isLoggedIn(req, res, next) {<br>        if (req.isAuthenticated())<br>            return next();<br>        res.redirect('/signin');<br>    }<br>}<br>

Now run the app and try to sign in. You should be able to sign in with any of the details you used while signing up, and you'll be directed to http://localhost:5000/dashboard/.

Congratulations if you made it to the end of this tutorial! We have successfully used Sequelize and Passport with a MySQL database.

In order to make our application a lot more appealing, we would add a bit of CSS styling. The codes for styling and the full code for this tutorial can be found on GitHub.

Conclusion

This concludes our tutorial on using Passport for authentication of users with Sequelize and MySQL. Sequelize is a really useful ORM for dealing with MySQL when using Node. I have personally found it to be very useful, and you should definitely consider using it in your next Node-MySQL app.

This post has been updated with contributions from Mary Okosun. Mary is a software developer based in Lagos, Nigeria, with expertise in Node.js, JavaScript, MySQL, and NoSQL technologies.

The above is the detailed content of Using Passport With Sequelize and MySQL. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn