Log Out

0_CyberLover_0·2022년 4월 24일
0

Node.JS #05

목록 보기
7/19

깃헙 프로필의 email이 데이터베이스에 있을때 유저가 로그인할 수 있게 해주었다.

그 말이 즉슨 Github가 주는 useremail을 쓰겠다는거다.

primary이면서 verifiedemail을 찾는다는 거다.

만일 찾았을 경우에 그 email을 데이터베이스에서 찾는거다.

만일 그 유저를 찾았다면 들어오게 할거다. 로그인 시킨다는 말이다.

그러면 누가 로그인되느냐 먼저 Github로 계정을 만든 사람이거나

usernamepassword로 계정을 만든 사람이 있는데 두 가지 경우 모두 로그인이

가능하다. 왜냐하면 같은 email이기 때문이다.

그래서 usernamepassword로 계정을 만든 사람의 경우 Github을 통해서 로그인도 가능하다.

왜냐하면 데이터베이스에 있는 emailGithub에 있는 email이 같다.

이런식으로 카카오톡으로 계정 생성하는것도 구현할수 있다.

만일 카카오톡이 emailreturn하면 그 email을 찾고 해당되는 유저를 찾아

로그인 시켜주는거다.

Github으로 계정을 만들었든 password로 만들었든지 간에 말이다.

이게 여기서 적용되는 규칮이다. user를 찾을 뿐이다.

어떤식으로 로그인 했는지는 관심없다. 어떤 식으로 계정을 만들었는지도 관심없고

Github가 준것과 똑같은 email을 찾게 되면 해당 user를 로그인 시킬거다.

DBGithub email을 가진 user가 없다면 새로운 계정을 만들어서

user를 로그인 시킬거다.

하지만 schema의 한 부분을 바꾼 적이 있다. 바로 socialOnly이다.

socialOnly는 해당 계정을 password로 로그인 할수 없다는 것을 알려준다.

이건 오직 소셜 로그인으로만 로그인 할수 있다는 말이다.

그래서 무얼 해볼수가 있냐면 postLogin으로 와서 username을 가진 유저를 찾을때

socialOnlyfalse인 유저만 찾게 만들수 있다.

export const postLogin = async (req, res) => {
  const { username, password } = req.body;
  const pageTitle = "Login";
  const user = await User.findOne({ username, socialOnly: false });

여기 postLogin에서 form에 입력한 username을 가지고

socialOnlyfalseuser를 찾는 거다.

왜냐하면 몇몇 사람들은 Github로 로그인 했는지 password를 통해 로그인했는지 잊어 버리기 때문이다.

그래서 여기서 뭘 하고 있냐면 Github데이터를 가지고 user를 생성하고 있고

 const user = await User.create({
        name: userData.name ? userData.name : userData.login,
        username: userData.login,
        email: emailObj.email,
        password: "",
        socialOnly: true,
        location: userData.location,
      });

user를 로그인시키고 있다. 근데 2번씩이나 반복하고 있다.

let existingUser로 수정해준다.

 let existingUser = await User.findOne({ email: emailObj.email });
    if (existingUser) {
      req.session.loggedIn = true;
      req.session.user = existingUser;
      return res.redirect("/");

그리고 만일 exstingUser가 없다면 이부분을 다 실행 할거다.

    let user = await User.findOne({ email: emailObj.email });
    if (!user) {
      user = await User.create({
        name: userData.name ? userData.name : userData.login,
        username: userData.login,
        email: emailObj.email,
        password: "",
        socialOnly: true,
        location: userData.location,
      });
    }
    req.session.loggedIn = true;
    req.session.user = user;
    return res.redirect("/");
  } else {
    return res.redirect("/login");
  }
};

그리고 마지막엔 이렇게 할거다. 그리고 existingUser대신 user라고 한다.

이렇게 user를 찾고 있고 이 유저를 찾게 되면 이 모든 것들을 건너뛰고 user를 로그인 할거다.

만일 user를 못 찾았다면 user를 새로 만든 user로 정의 할거다.

그리고 user를 로그인 할거다.

이미 저번 파트에서 Github 을 통해서 계정을 만들었다.

그래서 어떻게 작동하냐면 이 부분에서 로그인 될거다.

req.session.loggedIn = true;
    req.session.user = user;
    return res.redirect("/");

테스트해보겠다. 쿠키를 삭제해주고 새로고침을 하면 로그아웃이 되고

Continue with Github을 눌러서 로그인이 된다.

그리고 데이터베이스에는 한 user만 있다. 이건 socialOnlytrue인 경우에만 일어난다.

이말은 해당 계정은 Github로 만들어졌고 password가 없다는 소리이다.

모든 user를 지우고 쿠키도 지워 본다. 다시 로그아웃 되었다.

그리고 새로운 이메일로 가입을 해 보겠다.

user를 확인해 보면 socialOnlyfalse로 나온다.

그 다음에 Github을 이용해서 로그인해서 작동해 본다. 그리고 다시 user를 찾아 보면

socialOnlytrue로 나온다.

그리고 이제 웹사이트에 계정이 존재한다면 usernamepassword로 로그인했든

Github로 계정 생성을 했든 로그인 할거다.

Github에서 가져오는 데이터는 굉장히 중요한 것이다.

그러니 avatar_url을 저장해 볼수도 있다.

왜냐하면 다음 섹션에서 avatar와 파일들에 대해 다뤄 볼거다.

avatar_url: 'https://avatars.githubusercontent.com/u/91738673?v=4',

바로 이 url을 이용해서 말이다.

그래서 이걸 users schema에 추가해 볼거다.

User.js에서

const userSchema = new mongoose.Schema({
  avatar_url: String,

typestring으로 해준다. 그리고 required가 아니니깐 그냥 string만 적어준다.

이건 굉장히 유용하다. 왜냐하면 user들이 avatar를 가지고 있길 원한다.

그리고 Github은 필요한 링크를 준다. avatar_url을 클릭해보면 프로필 사진을 띄워 준다.

만일 userGithub으로부터 넘어왔다면 한가지를 더 추가해 본다.

avatar_url을 추가한다.

userController.js에서

user = await User.create({
        avatarUrl: userData.avatar_url,

그리고 user객체들은 전부 userData에서 온다는걸 기억하자.

그러니 userData.avatar_url을 쓰면 된다.

avatarUrl이 없는 useremailpassword로만 계정을 만들었다는 소리이다.

하지만 프로필 수정을 하면 바뀌게 된다.

다시 한번 기억해 본다. userDataAPI로 부터 오며 emailData 또한 Github API로부터 온다.

여기 만든 두개의 request가 있다.

const userData = await (
     await fetch(`${apiUrl}/user`, {
       headers: {
         Authorization: `token ${access_token}`,
       },
     })
   ).json();
   const emailData = await (
     await fetch(`${apiUrl}/user/emails`, {
       headers: {
         Authorization: `token ${access_token}`,
       },
     })
   ).json();

서로 다른 데이터에 접근 할수 있는 같은 토큰을 사용하고 있다.

이제 로그아웃 페이지를 만들어 본다.

로그아웃의 경우 보다시피 urllogout이라 되어 있다.

이게 Router상에 있는지 확인해 본다. 이미 가지고 있다.

Cannot GET /logout 으로 나오는 이유는 userRouter에 있어선 안된다.

/users/logout으로 있어햐 한다.

이말은 template를 후정해야 한다는 소리이다.

base.pug로 가서 /users/logout으로 바꿔준다.

if loggedIn
                        li 
                            a(href="/users/logout") Log Out

logout은 무얼 하고 있냐면 logout은 아무것도 안하고 있다.

그저 Log out을 보낸 뿐이다.

export const logout = (req, res) => res.send("Log out");

새로고침해서 확인하면 이제 로그아웃 페이지로 넘어가지만 어떤 작업도 하진 않는다.

export const logout = (req, res) => {
  req.session.destroy();
  return res.redirect("/");
};

이렇게 하면 세션을 없애준다. 그러면 이제 로그아웃을 페이지를 누르면 로그아웃 된다.

그리고 이제 /remove는 필요없어 졌으니 없애준다.

이제 Github인증과 로그아웃이 구현되었다.

profile
꿈꾸는 개발자

0개의 댓글