(김유선) 개인프로젝트 SSR로 처음부터 끝까지 진행하기 - 회원가입,로그인,로그아웃 기능

2024. 5. 9. 17:50프로젝트 일지

이것저것 찾아보다가

<script type="text/javascript"></script>

요걸 발견했다.

https://velog.io/@leyuri/script%EC%99%80-script-typetextjavascript%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94

 

<script>와 <script type="text/javascript">의 차이는?

나는 평소에 자바스크립트를 사용할 때 2번을 더 많이 사용했다. 하지만 이번에 jquery의 draggable를 사용해하는 상황에서 여러 예시 코드를 보다가 1번 처럼 자바스크립트를 사용하는 것을 보았다.

velog.io

굳이 아직은 쓸 필요 없을 것 같으니 참고만 하고 다음에 써야지

 

내가 지금까지 온클릭을 잘 안 쓰고 이벤트리스너만 써와서 오랜만에 온클릭으로 바꿔봤다.

<button type="submit" class="submit" onclick="same()">가입하기</button>
function same(){
        if($('#password').val()!=$('#password-confirm').val()){
          alert('입력하신 비밀번호가 다릅니다.')
        }}

온클릭에 함수 넣는 건 오늘이 처음인 듯

 

어제 문제였던 새로고침 현상 때문에 생각해보니

나는 위처럼 클라이언트 쪽에서 비밀번호 검사를 진행했는데

 

if(요청.body.password==요청.body.passwordconfirm){ // 입력한 비밀번호와 재입력 비밀번호가 같으면 진행
      let 해시 = await bcrypt.hash(요청.body.password, 10)
      await db.collection('user').insertOne({
        nickname : 요청.body.nickname,
        username : 요청.body.username,
        password : 해시
      })
      응답.json('가입되었습니다. 가입하신 계정으로 로그인해주세요.')
    }
    else{응답.redirect('/join')}

서버에서도 이렇게 비교를 해줬다.

이중으로 한 이유는 폼태그 자체에서 post요청을 해서 클릭 자체만으로 바로 post 요청이 가니까

클라이언트에서 사용자에게 오류를 alert창으로 보이게 해주고 실질적인 기능은 서버에서 해주니까 그렇다.

근데 이게 좀 이상하다는 생각이 들었다.

폼태그에서 post 요청을 보내기 전 조건을 거는 방법이 분명 있을 것 같다. 그걸 알아보겠다.

 

https://tyrionlife.tistory.com/200

 

[JS] DOM : form 태그 응용, 조건에 따른 submit 활용(onsubmit)

아래와 같이 onsubmit에 return false 라고 쓰면, submit 버튼을 눌러도 action이 가리키는 곳으로 이동하지 않는다. onsubmit 형태 onsubmit = "return false" onsubmit = "return true" 선택하세요 제목 작성자 어떤 조건

tyrionlife.tistory.com

역시나 있었다.

onsubmit 라는 것이 있었음

이 사람이 한 것처럼 나도 해보겠삼

 

<form action="/join" method="post" onsubmit="return false">

검증해봤는데 이렇게 입력하니까 정말 안 보내진다.

화면에도 아무런 변화없음(새로고침 같은 것도 안되는 듯)

너무 좋다.

 

계속 알아보니까 node.js는 서버에서 alert창을 띄워주는 방법은 없는 것 같더라

응답.json('<script>alert('ㅎㅇ')</script>')이런 식으로 할 수는 있는 것 같은데

다른 페이지로 이동해버려서 뒤로가기 해야 하고 뭐 다양한 문제가 있었음...

 

그래서 그냥 render로 덮어주기로 했음

이런 식으로 함

app.post('/join',async(요청,응답)=>{
  try{
      let 해시 = await bcrypt.hash(요청.body.password, 10)
      if(await db.collection('user').findOne({nickname : 요청.body.nickname})==null&&await db.collection('user').findOne({username : 요청.body.username})==null){ // 둘다 없으면
        await db.collection('user').insertOne({
          nickname : 요청.body.nickname,
          username : 요청.body.username,
          password : 해시
        })
        응답.render('join.ejs', {data : '가입되었습니다. 가입하신 계정으로 로그인해주세요.'})
      }
      else if(await db.collection('user').findOne({nickname : 요청.body.nickname})!=null&&await db.collection('user').findOne({username : 요청.body.username})==null){
        응답.render('join.ejs', {data : '닉네임이 중복됩니다. 다른 닉네임으로 가입해주세요'})
      }
      else if(await db.collection('user').findOne({nickname : 요청.body.nickname})==null&&await db.collection('user').findOne({username : 요청.body.username})!=null){
        응답.render('join.ejs', {data : '사용중인 이메일입니다. 다른 이메일로 가입해주세요'})
      }
      else{응답.render('join.ejs', {data : '닉네임과 이메일이 이미 사용중입니다. 변경 후 가입해주세요.'})}
  } catch(e){
    응답.render('join.ejs', {data : '입력하지 않은 값이 있거나 오류가 발생했습니다.'})
  }
})

코드는 이렇다.

잘 됨 ㅎㅎ

 

제출하면 입력해둔 게 날라가긴 하지만 그건 어쩔 수 없는 것 같다.

이렇게 회원가입은 다 됐고

<form action="/login" method="post">
                <input class="login _design" type="email" name="username" placeholder="이메일을 입력하세요" required>
                <input class="register _design" type="password" name="password" placeholder="비밀번호를 입력하세요" required>
                <input class="logingo _design" type="submit" value="로그인하기"></input>
            </form>
app.post('/login', async (요청, 응답, next) => {
  passport.authenticate('local', (error, user, info) => {
      if (error) return 응답.status(500).json(error)
      if (!user) return 응답.status(401).json(info.message)
      요청.logIn(user, (err) => {
        if (err) return next(err)
        응답.redirect('/')
      })
  })(요청, 응답, next)
})

로그인은 이렇게 했다.

계정 정보가 틀리면 이렇게 제이슨이 못생기게 보이지만 ㅜㅜ 너무 지쳐서 그냥 다른 것들부터 하겠음

 

그리고 로그아웃 기능도 만들었다.

<% if(user==undefined){ %>
                    <button class="login btn mg">로그인/회원가입</button>
                    <button class="login btn">마이페이지</button>
                <% } %>
                <% if(user!=undefined){ %>
                    <button class="logout btn mg1">로그아웃</button>
                    <button class="mypage btn">마이페이지</button>
                <% } %>

로그인 상태에 따라 이렇게 다르게 보이고

$('.logout').click(function(){
        $.get('/logout')
        .done(function(){
            alert('로그아웃 되었습니다.')
            location.reload() // 새로고침돼서 로그아웃하면 바로 로그인으로 바뀜
        })
    })

로그아웃 누르면 겟요청

app.get('/logout',(요청,응답)=>{
  요청.logout(async(err)=>{
    if (err) return next(err)
  })
  응답.redirect('/')
})

로그아웃은 그냥 요청.logout 하면 된다.