[항해99] 26일차 , 27일차 주특기 심화시작
항해 99
26 & 27 일차 :
주특기 심화 , Node JS 심화주가 시작되었다.
1주차에서는 기본 CRUD개념을 복습했다.
저번주에 만든 API를 보고 한번 복습하니깐 API만드는게 좀 익숙해진것같다.
JWT기본지식:
JWT - 로그인 기능 을 위한 기술인데 변조가 불가능하여 요즘 많이 쓰인다.
1.변조가 불가능하다
2. 하지만 열람은 아무나 가능하다.
그렇기 때문에 중요한 정보는 넣어서 보내지말자. 노출해도 되는 정보들만 ( user ID 등 ) 만 보내자.
쉽게:
토큰을 확인해보고 -> 토큰이 정상이면 -> 유저가 원하는 페이지를 보여준다.
로그인했으면 -> 토큰이있다
로그인 화면 추가 (Sign inAPI)
회원가입 추가 (Sign up API)
항상 sing in API -( GET/users/me) 을 호출하여 토큰을 가지고있는지 확인한다.
만약 토큰이 잘못되었으면 다시 로그인 페이지 호출
토큰이 있으면 -> 유저가 원하는 페이지를 보여줌
토큰이 없으면 -> 로그인 페이지 보여주기
목록페이지에서 로그인 페이지로 옮길때 토큰을 지워준다.
로그인 및 auth 부분 구현
API만들때 생각해보니깐 일반 유저가 api를 쓰진않을것같다. 그래서 사람들이 모두 router에 /api/ 지정해주고 그다음 주소를 만드는것같다.
1) 회원가입
강의에서 ajax통신에서 nickname, email,password,confirmpassword를 가져온다
$.ajax({
type: "POST",
url: "/api/users",
data: {
nickname: nickname,
email: email,
password: password1,
confirmPassword: password2,
},
success: function (response) {
customAlert("회원가입을 축하드립니다!", function () {
window.location.replace("/");
});
},
error: function (error) {
customAlert(error.responseJSON.errorMessage);
},
});
그러면 api에서 회원가입은 생성하는거니깐
post로한다. get으로할수도있지만 get은 body에 넣어서 데이터를 보내지않고 url? 이렇게 보내니깐 보안에안좋으니깐 post로쓴다.
ajax에서 받아온 nickname, email,passowrd,confirmpassword를 받고나서,
맨첫번쨰로 passwrod !== confrimpasword를 확인한다.
틀리면 바로 error message반환
맞으면, User를 user Schema로 해서 새로만들어주고 저장.
router.post("/users", async (req, res) => {
const { nickname, email, password, confirmPassword } = req.body;
if (password !== confirmPassword) {
res.status(400).send({ errorMessage: " Password not match" });
return;
}
const existsUsers = await User.find({
$or: [{ email }, { nickname }],
});
if (existsUsers.length) {
res.status(400).send({
errorMessage: " You already have same nickname or email ed",
});
return;
}
const user = new User({ email, nickname, password });
await user.save();
res.status(201).send({});
});
2) 로그인 기능
로그인 ajax
로그인은 email과 password를 보내준다.
function sign_in() {
let email = $("#inputEmail").val();
let password = $("#inputPassword").val();
$.ajax({
type: "POST",
url: "/api/auth",
data: {
email: email,
password: password,
},
success: function (response) {
localStorage.setItem("token", response.token);
window.location.replace("/goods.html");
},
error: function (error) {
customAlert(error.responseJSON.errorMessage);
},
});
}
로그인 API
첫번째로, req.body에서받아서 그값들을 db에서 찾아본다.
findOne대신 find를써도된다.
만약User가 존재하지않으면 에러
존재한다면, jwt userId를 토큰으로 반환해준다.
token을받아주면 ajax에서 setItem으로 localstorage에 넣어준다? -> 이부분은 공부가 더필요한것같다 이해안댐
router.post("/auth", async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email, password }).exec();
if (!user) {
res.status(401).send({ errorMessage: "email or password is not match" });
return;
}
const token = jwt.sign({ userId: user.userId }, "this_is_my_secret");
res.send({
token,
});
});
3) 인증 미들웨어
HTTP 인증할때 header 를사용해서 규격이나와있다.
header에다가 authorization + token내용:
Authorization: Bearer JWT토큰내용
https://developer.mozilla.org/ko/docs/Web/HTTP/Authentication
HTTP 인증 - HTTP | MDN
HTTP는 액세스 제어와 인증을 위한 프레임워크를 제공합니다. 가장 일반적인 인증 방식은 "Basic" 인증 방식입니다. 이 페이지에서는 일반적인 HTTP 인증 프레임워크를 소개하고 서버에 HTTP의 Basic
developer.mozilla.org
middlewears/auth-middleware.js
middleware basic frmae:
module.exports=(req,res,next)=>{
next(); // must be here for the middleware so it will pass to next
}
header에서 auhtorization을받아온다.
받은 authorization을 tokenType과 tokenValue로 나눠야해.
authorization에 Bearer이면, verfy 해야지. verify할때 key는 token만들때 key ("this_is_my_secret") 이랑 같아야해
verified된 id로 다시 db에서 찾아서 그값을
res.locals.user =user에다가 넣어서 보내준다
const jwt = require("jsonwebtoken");
const User = require("../models/user");
// header : Authorization :
module.exports = (req, res, next) => {
const { authorization } = req.headers;
const [tokenType, tokenValue] = authorization.split(" ");
console.log(tokenValue);
if (tokenType !== "Bearer") {
res.status(401).send({ errorMessage: "Login please " });
return;
}
try {
const { userId } = jwt.verify(tokenValue, "this_is_my_secret");
User.findById(userId)
.exec()
.then((user) => {
res.locals.user = user;
next(); // middleweare must have
});
} catch (error) {
res.status(401).send({ errorMessage: "Login please " });
return;
}
};
4) 내정보조회
function getSelf(callback) {
$.ajax({
type: "GET",
url: "/api/users/me",
headers: {
authorization: `Bearer ${localStorage.getItem("token")}`,
},
success: function (response) {
callback(response.user);
},
error: function (xhr, status, error) {
if (status == 401) {
alert("로그인이 필요합니다.");
} else {
localStorage.clear();
alert("알 수 없는 문제가 발생했습니다. 관리자에게 문의하세요.");
}
window.location.href = "/";
},
});
}
API
res.local에 넣어놓은 user 값을 가지고와서 email과 nickname을 가져오지.
router.get("/users/me", authMiddleware, async (req, res) => {
const { user } = res.locals;
console.log(user);
res.send({
user: {
email: user.email,
nickname: user.nickname,
},
});
});
어떤 20년차 개발자님의 블로그
JS기본 개념에대해 읽어보기좋은것같다.
Progmamming | PoiemaWeb
프로그래밍은 수행되어져야 하는 명령을 컴퓨터에 전달하는 일종의 커뮤니케이션이다. 이때
poiemaweb.com
'IT > Bootcamp 항해99' 카테고리의 다른 글
[항해99] 노드JS 심화반 숙제 (2) | 2021.07.07 |
---|---|
[항해99] 29일차 노드JS , 로그인 구현 , (0) | 2021.07.05 |
[항해99] 25일차 주특기 기본주차 숙제 마감, (0) | 2021.07.02 |
[항해99] 22일 & 23일차 Node JS (0) | 2021.06.30 |
[항해99] 21일차 Node JS (0) | 2021.06.28 |