ํฌ์ค์ฝ X ์ฝ๋ฉ์จ 7๊ธฐ 6์ฃผ์ฐจ ch1. MVCํจํด๊ณผ MYSQL์ฐ๋ํ๊ธฐ, Cookie, Session
ํฌ์ค์ฝ X ์ฝ๋ฉ์จ 7๊ธฐ 6์ฃผ์ฐจ์๋
form๊ตฌ์กฐ๋ก ๊ตฌํํ ๋ก๊ทธ์ธ, ๋ฐฉ๋ช ๋ก ๊ธฐ๋ฅ์
mvc๊ตฌ์กฐ๋ก ๋๋๊ณ , mysql์ ์ฐ๋ ํ ํ
๋ฐฉ๋ช ๋ก ๊ธฐ๋ฅ, ๋ก๊ทธ์ธ/ํ์๊ฐ์ ๊ธฐ๋ฅ์ ๊ตฌํํ์๋ค
๋ํ ์์์ ๊ตฌํํ ๋ก๊ทธ์ธ, ๋ฐฉ๋ช ๋ก ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ,
Sequelize๋ก ์ฌ๊ตฌ์ฑ ํ๋ ์๊ฐ์ ๊ฐ์ก๋ค.
๋ ๋ฐ๋ก ๋น๋ฐ๋ฒํธ ์ํธํ ํ๋ ๋ฐฉ๋ฒ,
cookie, seesion์ ๋ํ ์ง๋๋ ๋๊ฐ๋ค.
์ด๋ชจ๋ ๊ฒ์ด ์ผ์ฃผ์ผ ๋ง์ ๋๊ฐ ์ง๋๋ผ
๋ค๋ฐ๋ผ ๊ฐ๋๋ผ ์ ์ข ๋จน์๋ค.
๋จ๊ธฐ๊ฐ์ ๋ง์ ๊ฒ์ ๋ฐฐ์ด ํ์ธ์ง,
์๋๋ฉด ๋ด๊ฐ ์์ ์๊ฐ์ ์ง์ค์ ๋ชป ํ ํ์ธ์ง
๋ง์ด ํท๊ฐ๋ฆฐ๋ค,,
์ผ๋จ MVCํจํด๊ณผ MYSQL์ฐ๊ฒฐํ๋ ๋ฒ์ ๋ํด์ ๋จผ์
๋ฆฌ๋ทฐํด๋ณด๊ณ ,
Ssequelize์ ๋ํด์๋ ๋ฆฌ๋ทฐํด ๋ณด๋๋ก ํ๊ฒ ๋ค!
์์ ๋ฆฌ๋ทฐ์ ์์ ํท๊ฐ๋ฆฌ๋ ๊ฑฐ ! ์ฐพ์๋ณธ ๊ฑฐ ๊ธฐ๋ก
โ legacy์ sequelize์ ์ฐจ์ด
- Legacy:
- Legacy๋ ์ผ๋ฐ์ ์ผ๋ก ORM(Object-Relational Mapping)์ด๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ธฐ์กด์ ๋ฐฉ์์ ์๋ฏธํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ์ํด ์ง์ SQL ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ์ง์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
- ๊ฐ๋ฐ์๊ฐ ์ง์ SQL ๋ฌธ๋ฒ์ ์ต์ํด์ผ ํ๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ๋ํ ์ธ๋ถ ์ฌํญ์ ๊ด๋ฆฌํด์ผ ํฉ๋๋ค.
- ์ง์ SQL์ ์์ฑํ๊ณ ์คํํ๊ธฐ ๋๋ฌธ์ ์ธ๋ฐํ ์ ์ด์ ์ต์ ํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ํ์ง๋ง SQL ๋ฌธ๋ฒ์ ๋ํ ์ดํด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์์ ์ ๋ํ ์ถ๊ฐ์ ์ธ ์์ ์ด ํ์ํฉ๋๋ค.
- Sequelize:
- Sequelize๋ JavaScript ๊ธฐ๋ฐ์ ORM(Object-Relational Mapping) ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ์ํด JavaScript ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ ์ ์์ต๋๋ค.
- SQL ์ฟผ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์์ฑํ๊ณ ์คํํ๊ธฐ ๋๋ฌธ์ SQL ๋ฌธ๋ฒ์ ๋ํ ์ดํด๋ฅผ ํฌ๊ฒ ์๊ตฌํ์ง ์์ต๋๋ค.
- Sequelize๋ ๋ค์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ ๊ณผ ํธํ๋๋ ORM์ผ๋ก, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ ์ด์์ฑ์ ์ ๊ณตํฉ๋๋ค.
- ๋ชจ๋ธ๊ณผ ๊ด๊ณ ์ค์ , ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ, ์ฟผ๋ฆฌ ์์ฑ ๋ฐ ์คํ, ๊ฒฐ๊ณผ ์ฒ๋ฆฌ ๋ฑ์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
- Sequelize๋ ORM ํจํด์ ๋ฐ๋ฅด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ ๊ฐ์ฒด ์งํฅ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ ์์ฉํ ์ ์์ต๋๋ค
- ์์ฝํ๋ฉด, Legacy๋ ๊ธฐ์กด์ SQL ์ฟผ๋ฆฌ ์์ฑ ๋ฐ ์ง์ ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ ์์ฉ์ ์์กดํ๋ ๋ฐฉ์์ ๋๋ค. ๋ฐ๋ฉด์ Sequelize๋ ORM ํจํด๊ณผ JavaScript ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ํธ ์์ฉํ๋ฉฐ, SQL ์ฟผ๋ฆฌ ์์ฑ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์์ ์ ๋จ์ํํ๋ ๋ฐ ์ค์ ์ ๋ก๋๋ค. Sequelize๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ๋ํ ์ธ๋ถ ์ฌํญ์ ์ถ์ํํ๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง ๋ณด์์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์ํ๋ผ์ด์ฆ๋ก ์์ฑํ๊ฒ ๋๋ฉด,
controller์ ๊ฒฝ๋ก, sequelize์ฟผ๋ฆฌ๋ฌธ์ ๊ธฐ์ฌํ๊ณ ,
model์๋ mysql์ ๋ณด๋ฅผ ๊ธฐ์ฌํ๋ค
MVCํจํด๊ณผ MYSQL์ฐ๋ํ๊ธฐ
์ผ๋จ ๋ค์๊ธ ์๊ธฐ ์์ผ๋ณด๋
MVCํ๋ฆ ..
ํ์ผ ๊ตฌ์กฐ๋ ์ด๋ ๋ค!
๊ตฌํํด ๋ณผ ๊ฒ!
npm install mysql
์ ์ ๋ ฅํ์ฌ mysql์ ์ค์นํ์ฌ ์ค๋ค.
model/visitor.js
- ์ธ๋ถ์์ ์ต์์ root๊ณ์ ์ผ๋ก์ ๋น๋ฐ๋ฒํธ ์ ๊ทผ์ ํ์ฉํ์ง ์๋๋ค.
- mysql์์ root๊ณ์ ์ผ๋ก์ ์ ๊ทผ์ ํ์ฉํ์ง ์๋ ์ด์ ๋
๋ณด์๊ณผ ๊ด๋ จ์ด ์๋ค. root๊ณ์ ์ mysql์์ ๊ฐ์ฅ ๋์ ๊ถํ์ ๊ฐ์ง๋ ์ฌ์ฉ์ ๊ณ์ ์ผ๋ก,
๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ๊ด๋ จ๋ ๋ชจ๋ ์์ ์ ๋ํ ๊ถํ์ ๊ฐ๋๋ค.
๋ฐ๋ผ์ root๊ณ์ ์ด ์ธ๋ถ์์ ์ ๊ทผ ๊ฐ๋ฅํ ์ํ๋ก ์ค์ ๋์ด ์๋ค๋ฉด,
ํด์ปค๋ ์ ์์ ์ธ ์ฌ์ฉ์์๊ฒ ํฐ ์ํ์ด ๋ ์ ์๋ค.
- ์ฆ, ์๋ก์ด์ฌ์ฉ์ (user ๊ณ์ ) ๋ฅผ ๋ง๋ค๊ณ
๊ทธ ์ฌ์ฉ์๋ก ์ ๊ทผ์ ํด์ผํ๋ค.
ํฐ๋ฏธ๋ ์ฐฝ์์ mysql์ฌ์ฉ์ ์ถ๊ฐํ๊ณ , db์ ๊ถํ ๋ถ์ฌํ๊ธฐ
model/Visitor.js>
โ์ฝ๋ฐฑํจ์๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋?
- ์ฝ๋ฐฑํจ์๋ ๋น๋๊ธฐ์ ์์ ์ด ์๋ฃ๋์์ ๋ ์คํ๋๋ ํจ์์ด๋ค.
- ์์ ์ฝ๋์์ exports.MgetVisitor1 ํจ์๋ mysql์ฟผ๋ฆฌ๋ฅผ์คํํ์ฌ
๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ์์ ์ ์ํํ๋ค.
์ด๋, ์ฝ๋ฐฑํจ์๋ฅผ ์ธ์๋ก ์ ๋ฌํ์ฌ
๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ณ ์ฒ๋ฆฌํ ์ ์๋ค.
- ์ด๋ฅผ ํตํด ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋์์ ๋,
'rows'๋ฅผ ์ ๋ฌ๋ฐ์ ์ํ๋ ๋ก์ง์ ์ํํ ์ ์๋ค.
-์ฝ๋ฐฑํจ์ ๋์ , promises๋ async/await์ ๊ฐ์
๋น๋๊ธฐ ์ ์ด ํจํด์ ์ฌ์ฉํ์ฌ๋ ๋น์ทํ ๊ฒฐ๊ณผ๋ฅผ ์ป์์ ์๋ค.
controller/visitor.js>
- res.render("visitor", {data: result});;๋ฐฉ๋ฌธ์ ๋ฐ์ดํฐ๋ฅผ
visitorํ์ด์ง์ ์ ๋ฌํ๊ณ ํด๋น ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋ค.
router>
์ธ์ (Session)๊ณผ ์ฟ ํค(Cookie)์ ์ฐจ์ด
1. ์ธ์ (Session)
- ์ธ์ ์ ์๋ฒ ์ธก์์ ์ฌ์ฉ์ ์ํ๋ฅผ
์ถ์ ํ๊ธฐ ์ํด ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์
- ์ฌ์ฉ์๊ฐ ์น ์ฌ์ดํธ์ ์ ์ํ๋ฉด
์๋ฒ๋ ๊ณ ์ ํ ์ธ์ ์๋ณ์๋ฅผ ์์ฑํ๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌ
- ํด๋ผ์ด์ธํธ๋ ์ด ์ธ์ ์๋ณ์๋ฅผ ์ฟ ํค๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฅํ๊ฑฐ๋
url์ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์์ ์ ๋ฌ
- ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์ธ์ ์๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก
์ฌ์ฉ์์ ์ธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌ
ex. ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ ์ธ์ ์ ์์ฑํ๊ณ ์ธ์ ์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์ ์ฅํ์ฌ
์ธ์ฆ๋ ์ํ๋ฅผ ์ ์งํ๋๊ฒฝ์ฐ
2. ์ฟ ํค(Cookie)
- ์ฟ ํค๋ ํด๋ผ์ด์ธํธ ์ธก์์ ์ฌ์ฉ์ ์ํ๋ฅผ ์ถ์ ํ๊ธฐ ์ํด
ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์
- ์๋ฒ๋ ํด๋ผ์ด์ธํธ์๊ฒ ์ฟ ํค๋ฅผ ์ค์ ํ์ฌ
ํด๋ผ์ด์ธํธ๊ฐ ๋ค์ ์์ฒญํ ๋ ๋ง๋ค ์ฟ ํค๋ฅผ ํจ๊ป ์ ์ก
- ์๋ฒ๋ ํด๋ผ์ด์ธํธ๊ฐ ์ ์กํ ์ฟ ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก
์ฌ์ฉ์์ ์ํ๋ฅผ ์ถ์ ํ๊ณ ๊ด๋ฆฌ
ex. ์ผํ ์น ์ฌ์ดํธ์์ ์ฅ๋ฐ๊ตฌ๋์ ์ํ์ ์ถ๊ฐํ๊ณ ,
ํด๋ผ์ด์ธํธ์ ์ฟ ํค์ ์ฅ๋ฐ๊ตฌ๋ ์์ดํ ์ ์ ์ฅํ์ฌ
๋ค์ ๋ฐฉ๋ฌธ์์๋ ์ฅ๋ฐ๊ตฌ๋์ ์ํ์ด ์ ์ง๋๋ ๊ฒฝ์ฐ
โ์ธ์ ๊ณผ ์ฟ ํค์ ๋ณด์๊ณผ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ
์ธ์ ์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ๋๋ฌธ์
์ผ๋ฐ์ ์ผ๋ก ์ฟ ํค๋ณด๋ค ์์ ํ๋ค.
๊ทธ๋ฌ๋, ์ธ์ ์ ์๋ฒ ์ธก ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ฏ๋ก
์๋ฒ์ ๋ถํ๋ฅผ ์ฆ๊ฐ์ํฌ ์ ์๋ค.
๋ฐ๋ฉด, ์ฟ ํค๋ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ฏ๋ก
์๋ฒ ๋ถํ๋ ๊ฐ์ํ์ง๋ง,
ํด๋ผ์ด์ธํธ์์ ์์ ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ณด์์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ
์ ์ฅํ๋ ๋ฐ๋ ์ ํ์ด ์๋ค.
Cookie ์ฌ์ฉํ๊ธฐ
๐cookie์ฌ์ฉ์ ํ์ํ ์ค์น , ๋ฉ์๋ ๋ฑ
npm install cookie-parser //์ฟ ํค ์ค์นํ๊ธฐ
const cookieParser = require("cookie-parser");
app.use(cookieParser());
// cookie-parser ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ
res.cookie('์ฟ ํค์ด๋ฆ', '์ฟ ํค๊ฐ', '์ต์
๊ฐ์ฒด');
//expressํ๋ ์์ํฌ์์ ์ฌ์ฉ๋๋ ๋ฉ์๋, ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ์ฟ ํค๋ฅผ ์ค์ ํ ๋ ์ฌ์ฉ
๐Cookie ์์
cookies.js ์ฃผ์์ฝ๋!
app.use(cookieParser());
app.get("/", (req, res) => {
res.render("index", { data: req.cookies.popup });
});
app.post("/setCookie", (req, res) => {
res.cookie("popup", "hide", {
maxAge: 60 * 1000,
});
res.send({ result: true });
});
popup ์ด๋ผ๋ ์ด๋ฆ์ผ๋ก hide๊ฐ์ ๊ฐ์ง๋ ์ฟ ํค๋ฅผ ์ค์ ํ๋ค.
์ด๋ ํด๋ผ์ด์ธํธ์ ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค๋ฅผ ์ ์กํ์ฌ ์ ์ฅ
/setCoolie๊ฒฝ๋ก๋ก post์์ฒญ์ด ๋ค์ด์จ ๊ฒฝ์ฐ
'popup'์ด๋ผ๋ ์ด๋ฆ์ ์ฟ ํค๋ฅผ ์ค์ ํ ํ,
{result: true}๋ผ๋ json์๋ต์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋ด๋ ๊ธฐ๋ฅ์ ์ํํ๋ค.
index.ejs ์ฃผ์ ์ฝ๋!
const myModal = new bootstrap.Modal("#exampleModal");
if ("<%= data %>" === "") {
myModal.show();
}
function closeModal() {
axios({
method: "POST",
url: "/setCookie",
}).then((res) => {
console.log(res.data);
});
myModal.hide();
}
axios๋ฅผ ์ฌ์ฉํ์ฌ post๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ /setCookie๋ก ์์ฒญ์ ๋ณด๋ธ๋ค
์ด๋ ์๋ฒ ์ถ์์ ์ฟ ํค๋ฅผ ์ค์ ํ๊ธฐ ์ํ ์์ฒญ์ด๋ค
axios์ then() ๋ฉ์๋๋ ์๋ฒ์์ ์๋ต์ด ๋์ฐฉํ ํ์
์คํ๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ ์ํ๋ค.
res๋งค๊ฐ๋ณ์๋ ์๋ฒ์ ์๋ต์ ๋ํ๋ธ๋ค
์์ฒญ์ ๋ํ ์๋ต์ ๋ฐ์ผ๋ฉด, ์ฝ์์ ์ถ๋ ฅํ ํ์ ๋ชจ๋ฌ์ฐฝ์ ์จ๊ธฐ๋ ์ญํ
Session ์ฌ์ฉํ๊ธฐ
- ์น ์๋ฒ์ ์ ์ฅ๋๋ ์ฟ ํค
- ์ฌ์ฉ์๊ฐ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์ ์ํ ์์ ๋ถํฐ
์ฐ๊ฒฐ์ ๋๋ด๋ ์์ ๊น์ง์ ์๊ฐ ๋์ ์ผ๋ จ์ ์๊ตฌ๋ฅผ ํ๋์ ์ํ๋ก ๋ณด๊ณ
๊ทธ ์ํ๋ฅผ ์ ์ง์ํจ๋ค.
ex) ๋ก๊ทธ์ธ ์ ์ง
npm install express-session //session ์ฌ์ฉ ์ ์ค์น ๋ชจ๋
const session = require('express-session');
app.use(seesion('์ต์
๊ฐ์ฒด'));
// session ๋ฏธ๋ค์จ์ด
req.session.id = req.body.id;
//req.session.key = value
๐ Session ์์
session.js ์ฃผ์ ์ฝ๋!
const userInfo = { id: "abc", pw: "123" };
app.use(
session({
secret: "mysecretKey",
resave: false,
saveUninitialized: true,
})
);
if (user === undefined) {
res.render("app", { isLogin: false });
} else {
res.render("app", { isLogin: true, user: user });
}
app.post("/login", (req, res) => {
console.log(req.body);
if (req.body.id === userInfo.id && req.body.pw === userInfo.pw) {
req.session.user = req.body.id;
res.redirect("/");
} else {
res.send({ result: false });
}
});
์ธ์ ์ค์
express-session์ express์ ํ๋ฆฌ์ผ์ด์
์์ ์ธ์
๊ด๋ฆฌ๋ฅผ ์ํ ๋ฏธ๋ค์จ์ด๋ก ์ฌ์ฉ
secret: ์ธ์
์ ์ํธํ ํ๊ธฐ ์ํ ๋น๋ฐํค, ์ด ๋น๋ฐํค๋ ์ธ์
๋ฐ์ดํฐ๋ฅผ ์ํธํํ๊ณ ,๋ณตํธํ ํ๋๋ฐ ์ฌ์ฉ
resave: ๋ณ๊ฒฝ์ฌํญ์ด ์๋๋ผ๋ ์ธ์
์ ๋ค์ ์ ์ฅํ ์ง ์ฌ๋ถ๋ฅผ ์ค์ ,
์ผ๋ฐ์ ์ผ๋ก false๋ก ์ค์ ํ์ฌ ๋ณ๊ฒฝ์ฌํญ์ด ์์ ๊ฒฝ์ฐ, ์ธ์ ์ ๋ค์ ์ ์ฅํ์ง ์๋๋ก ํจ
saveUninitialized : ์ด๊ธฐํ ๋์ง ์์ ์ธ์
๋ ์ ์ฅํ ์ง ์ฌ๋ถ ์ค์ ,
์ผ๋ฐ์ ์ผ๋กtrue๋ก ์ค์ ํ์ฌ ๋ชจ๋ ์์ฒญ์ ๋ํด ์ธ์ ์ ์ ์งํ๋ ๊ฒ์ ๊ถ์ฅ
res.redirect("/")๋ฅผ ์ฐ๋ ์ด์ ?
render๋ ํ ํ๋ฆฟ์ ๋ถ๋ฌ์ค๊ณ , redirect๋ url๋ก ์ด๋์ ํ๋ค.
url๋ก ์ด๋ํ๋ค๋ ๊ฒ์ ๊ทธ url์ ๋ง๋ views๊ฐ ๋ค์ ์คํ๋๊ณ ,
์ฌ๊ธฐ์ render๋ฅผ ํ ์ง ๋ค์ redirectํ ์ง ๊ฒฐ์
ํ์ด๋ผ์ดํธ์ธ ์ํ๋ผ์ด์ฆ์ ๋ํ ๋ด์ฉ์
๋ค์ ๊ธ์์ ์์ฑํ๋๋ก ,,