Node.JS로 인증/인가를 구현할 때는 지금까지 사용해 온 방식을 사용할 수도 있지만 Passport라는 모듈을 이용해서 구현하면 훨씬 깔끔하게 인증/인가 부분을 구현할 수 있습니다.
그래서 이제부터는 Passport 모듈을 이용해서 구현해 보겠습니다.
Passport를 이용해서 만들 앱은 이메일과 비밀번호를 이용해서 로그인하는 것과 구글 아이디를 이용하는 OAuth 로그인을 할 수 있는 앱을 구현해 보겠습니다.
models, views, controllers, services
yarn add dotenv express nodemon body-parser cookie-parser cors mongoose passport passport-local passport-google-oauth20 passport-kakao bcryptjs ejs
// server.js
const mongoose = require("mongoose");
const express = require("express");
const path = require("path");
require("dotenv").config();
const app = express();
const port = 3000;
const { MONGO_USERNAME, MONGO_PASSWORD } = process.env;
app.use("/static", express.static(path.join(__dirname, "public")));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
mongoose
.connect(`mongodb+srv://${MONGO_USERNAME}:${MONGO_PASSWORD}@test.vi6echp.mongodb.net/`)
.then(() => console.log("mongodb connected"))
.catch((err) => console.log(err));
app.listen(port, () => {
console.log(`Listening on ${port}...`);
});
// models/users.model.js
const mongoose = require("mongoose");
const userSchema = mongoose.Schema({
// 일반 로그인
email: { type: String, trim: true, unique: true },
password: { type: String, minLength: 5 },
// 구글 로그인
googleId: { type: String, unique: true, sparse: true },
});
const User = mongoose.model("User", userSchema);
module.exports = User;
// server.js
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
<!-- login.ejs -->
<section class="prompt">
<h1>Login</h1>
<form action="/login" method="post">
<section>
<label for="email">Email</label>
<input type="text" id="email" autocomplete="email" required autofocus />
</section>
<section>
<label for="current-password">Password</label>
<input type="password" id="current-password" name="password" autocomplete="current-password" required />
</section>
<input type="hidden" />
<button type="submit">Login</button>
</form>
<p class="help">Don't have an account? <a href="/signup">Signup</a></p>
</section>
<!-- signup.ejs -->
<section class="prompt">
<h1>Signup</h1>
<form action="/signup" method="post">
<section>
<label for="email">Email</label>
<input type="text" id="email" name="email" autocomplete="email" required />
</section>
<section>
<label for="new-password">Password</label>
<input type="password" id="new-password" name="password" autocomplete="new-password" required />
</section>
<input type="hidden" />
<button type="submit">Sign up</button>
</form>
<p class="help">Already have an account? <a href="/login">Login</a></p>
</section>
// server.js
app.get("/login", (req, res, next) => {
res.render("login");
});
app.post("/login", (req, res, next) => {});
app.get("/signup", (req, res, next) => {
res.render("signup");
});
app.post("/signup", (req, res, next) => {});
// server.js
app.post("/signup", async (req, res, next) => {
const user = new User(req.body);
console.log(req.body); // email password
try {
await user.save(); // database save
return res.status(200).send({ success: true });
} catch (error) {
console.log(error);
}
});