{"id":1154,"date":"2025-04-18T09:42:49","date_gmt":"2025-04-18T09:42:49","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=1154"},"modified":"2025-04-18T10:37:37","modified_gmt":"2025-04-18T10:37:37","slug":"nodejs7-login-logout","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/04\/18\/nodejs7-login-logout\/","title":{"rendered":"nodejs7 &#8211; \ub85c\uadf8\uc778,\ub85c\uadf8\uc544\uc6c3(\ubc30\uc5f4)\/Login ,Logout(Array)"},"content":{"rendered":"\n<p>Login ,Logout<\/p>\n\n\n\n<p>server1.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require('express');\nconst session = require('express-session');\nconst bcrypt = require('bcrypt');\nconst app = express();\nconst port = 3000;\n\n\/\/ \uac04\ub2e8\ud55c \uc0ac\uc6a9\uc790 \ub370\uc774\ud130\ubca0\uc774\uc2a4 (\ubc30\uc5f4) : simple user database (array)\nconst users = &#91;\n  { id: 1, username: 'testuser', passwordHash: '$2b$10$abKhb8aJsQ02T2TwSi0J4eVK42eRojFDTe.3EmWUQkdiXvaFVboxq' } \/\/ '11111111'\uc758 hash\n];\n\n\/\/ \ubbf8\ub4e4\uc6e8\uc5b4 \uc124\uc815 : middleware settings\napp.use(express.urlencoded({ extended: false }));\napp.use(express.json());\napp.use(session({\n  secret: 'your-secret-key',\n  resave: false,\n  saveUninitialized: false,\n  cookie: { secure: false }\n}));\n\n\/\/ \ub85c\uadf8\uc778 \uc0c1\ud0dc \ud655\uc778 \ubbf8\ub4e4\uc6e8\uc5b4 (\ubaa8\ub4e0 \uc694\uccad\uc5d0\uc11c \uc2e4\ud589) : middleware for loging status checking \napp.use((req, res, next) =&gt; {\n  res.locals.member = req.session.userid;\n  res.locals.isLoggedIn = !!req.session.userId;\n  res.locals.loggedInUser = users.find(user =&gt; user.id === req.session.userId) || null;\n  next();\n});\n\napp.use((req, res, next) =&gt; {\nres.locals.userid = \"\";\nres.locals.name = \"\";\n\nif(req.session.member){\n  res.locals.userid = req.session.member.userid;\n  res.locals.name = req.session.member.name;\n}\n  next();\n});\n\n\/\/ \ubdf0 \uc5d4\uc9c4 \uc124\uc815 (ejs \uc0ac\uc6a9) : 'view engine settings(use ejs)\napp.set('view engine', 'ejs');\napp.set('views', '.\/public');\n\n\/\/ \uc815\uc801 \ud30c\uc77c \uc81c\uacf5 (css \ub4f1) : static file setting (css) \napp.use(express.static('public'));\n\n\/\/ bcrypt\ud328\uc2a4\uc6cc\ub4dc \uc0dd\uc131 : generate bcrype password\nasync function generateHash(password) {\n  try {\n      const saltRounds = 10;\n      const hash = await bcrypt.hash(password, saltRounds);\n      console.log(\"\ud574\uc2dc\ub41c \ube44\ubc00\ubc88\ud638:\", hash);\n      return hash;\n  } catch (err) {\n      console.error(\"\ud574\uc2f1 \uc624\ub958:\", err);\n  }\n}\n\n\/\/ \ub8e8\ud2b8 \ub77c\uc6b0\ud130 : root router\napp.get('\/', (req, res) =&gt; {\n  res.render('login');\n});\n\n\/\/ \ub85c\uadf8\uc778 \ud3fc \ud45c\uc2dc :  login form \napp.get('\/login', (req, res) =&gt; {\n  res.render('login');\n});\n\n\/\/ \ub85c\uadf8\uc778 \ucc98\ub9ac : login process\napp.post('\/loginProc', async (req, res) =&gt; {\n  const { username, password } = req.body;\n  const user = users.find(u =&gt; u.username === username);\n  \n  \/\/ generate bcrypt password\n  \/\/ const bbcrypt = generateHash(password);\n  \/\/ console.log(bbcrypt);\n  \n  \n  if (!user) {\n    return res.send('\ub85c\uadf8\uc778 \uc2e4\ud328 login failed: \uc0ac\uc6a9\uc790 \uc5c6\uc74c cannot find user');\n  }\n\n  \/\/ search user\n  const isMatch = await bcrypt.compare(password, user.passwordHash);\n\n  if (isMatch) {\n    req.session.member = {\n      userid: req.body.username, \/\/ \n      name: 'anomymous' \/\/ \n  };\n    res.redirect('\/');\n  } else {\n    res.send('\ub85c\uadf8\uc778 \uc2e4\ud328 login failed: \ube44\ubc00\ubc88\ud638 \ubd88\uc77c\uce58 password error');\n  }\n});\n\n\/\/ \ub85c\uadf8\uc544\uc6c3 \ucc98\ub9ac : logout process\napp.get('\/logout', (req, res) =&gt; {\n  req.session.destroy((err) =&gt; {\n    if (err) {\n      console.error('\uc138\uc158 \uc0ad\uc81c \uc2e4\ud328 session delete failed:', err);\n      res.send('\ub85c\uadf8\uc544\uc6c3 \uc2e4\ud328 logout failes');\n    } else {\n      res.redirect('\/');\n    }\n  });\n});\n\napp.listen(port, () =&gt; {\n  console.log(`\uc11c\ubc84\uac00 http:\/\/localhost:${port} \uc5d0\uc11c \uc2e4\ud589 \uc911\uc785\ub2c8\ub2e4.`);\n});\n\n\/\/npm install express, express-session, bcrypt<\/code><\/pre>\n\n\n\n<p>\/public\/login.ejs<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Login&lt;\/title&gt;\n    &lt;style&gt;\n    input&#91;type=\"submit\"] {\n        background-color: #4CAF50;\n        color: white;\n        padding: 10px 20px;\n        border: none;\n        border-radius: 4px;\n        cursor: pointer;\n    }\n    input&#91;type=\"submit\"]:hover {\n        background-color: #45a049;\n    }\n    input&#91;type=\"text\"],\n    input&#91;type=\"password\"],\n    textarea,\n    select {\n        width: 40%; \/* \uc785\ub825 \ud544\ub4dc\uc758 \uac00\ub85c \uc0ac\uc774\uc988\ub97c \ud3fc\uc5d0 \ub9de\ucda4 *\/\n        padding: 8px;\n        margin-bottom: 10px;\n        border: 1px solid #ccc;\n        border-radius: 4px;\n        box-sizing: border-box;\n    }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div&gt;\n        &lt;%if(locals.userid){ %&gt; ID:&lt;%= locals.userid %&gt; \uc774\ub984:&lt;%= locals.name%&gt; \n            &lt;a href=\"\/logout\"&gt;Log out&lt;\/a&gt;\n        &lt;%}else{%&gt;\n            &lt;form id=\"loginForm\" action=\"\/loginProc\" method=\"post\"&gt;\n\n                &lt;label for=\"title\"&gt;Login:&lt;\/label&gt;\n                &lt;input type=\"text\" id=\"username\" name=\"username\" required&gt;&lt;br&gt;&lt;br&gt;\n    \n                &lt;label for=\"title_group\"&gt;Password:&lt;\/label&gt;\n                &lt;input type=\"password\" id=\"password\" name=\"password\" required&gt;&lt;br&gt;&lt;br&gt;\n    \n                &lt;input type=\"submit\" value=\"submit\"&gt;\n            &lt;\/form&gt;  \n        &lt;%}%&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Login ,Logout server1.js \/public\/login.ejs<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-1154","post","type-post","status-publish","format-standard","hentry","category-nodejs","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=1154"}],"version-history":[{"count":2,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1154\/revisions"}],"predecessor-version":[{"id":1160,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/1154\/revisions\/1160"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=1154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=1154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=1154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}