
서로를 모르는 것을 알게 만들게 하기 위한 방법이 인증이다.
인증을 위해서는 어떤 사용자가 요청을 보내는지의 대한 정보를 서버가 알게 해야한다.
사용자의 정보를 서버에게 전달하는 곳은 보통 HTTP request.headers 에 담겨서 보낸다.
하지만 브라우저에서는 개발자 툴을 통해서도 쉽게 정보의 송수신을 확인할 수 있다. 따라서 사용자 정보는 쉽게알아볼 수 없는 방식으로 서버에 전달되어야 한다.
쿠키는 서버가 사용자 브라우저에 보내는 4kbyte 작은 단위의 정보이다.
브라우저는 그것을 저장할 수도 있고 다시 후에 동일한 서버에 돌려보낼수도 있다.
따라서 서로 다른 두개의 요청이 동일한 서버에 들어와도 서버는 쿠키를 통해서 누가 누군지 구분할 수 있게 된다.
ℹ️ HTTP로 하여금 원래 stateless한데 stateful한 기능을 해주게 도와주는 놈이라는 뜻.
보통 세가지의 목적으로 사용된다.
Session management
: Logins, shopping carts, game scores, or anything else the server should remember
Personalization
: User preferences, themes, and other settings
Tracking
:Recording and analyzing user behavior
과거에는 물론 현재도 사용하지만 localStorage랑 sessionStorage가 생기기 이전에는 브라우저의 저장소 같은 역활을 했지만 지금은 아니다. 쿠키는 매요청시마다 함께 전송이 되기때문에 성능저하의 요인도 있고 최근에 위에 언급한 다른 StorageAPI나 IndexedDB가 있기 때문이다.
쿠키는 서버가 요청을 받은 다음 Set-Cookie 라는 헤더에 응답과 함께 보낼 수 있다.

세션 ID에는 사용자에 대한 아무런 정보가 담겨있지 않지만 이 세션ID를 통해서 서버는 이 사용자가 누구인지 판단할 수 있다.
ℹ️ 따라서 세션ID를 훔친다면 다른 사람을 흉내내서 로그인을 할 수 있다.
세션은 서버측에서 저장하고 있는 데이터이다. 쿠키기반으로 생성하며 쿠키기반의 생성세션은 로그인상태를 유지하기 위해 많이 사용한다. 로그인 후 유저관한등을 저장하며 api 호출시 세션에 저장된 유저 권한으로 인가를 한다.
express 에서는 보통 express-session이라는 라이브러리를 통해서 세션을 생성할 수 있다. 이 미들웨어를 사용하면 req.session이라는 객체가 생성되고
디폴트로 서버의 메모리에 저장된다.
메모리는 휘발성이라서 서버가 종료되면 세션정보가 다 사라진다.
따라서 redis, mysql, file 등의 형태로 저장한다.
세션데이터를 어떤 데이터로 저장할지 정해야한다.
보통 이메일이나 비밀번호는 DB에 저장하지 세션으로 저장하지 않는다.
보통 이사람이 로그인 했는지여부, 페이지 접근시 사용자의 닉네임이나 권한등을 저장하면 DB에 다시 접속할 필요가 없어서 효율적이다.
💁💁💁💁
node js에서 인증을 위해 사용하는 라이브러리
passport 사용법과 개념의 자세한 설명은 passport번역링크 참조

구현시 개인적으로는 위와 같은 구조로 보통 만든다.
index.js 에는 passport의 serialize, deserialize 로직을 넣어준다. 그리고 전략으로 사용할 인증도구들은 import해서 호출해준다.
local.js 는 이메일 비밀번호등의 형태 인증전략구현
routes/auth.js 는 로그인버튼 클릭시의 백엔드 라우트. 이 안에서 로컬전략을 호출해주고 local.js에서 구현한 콜백들이 넘어온다. 그럼 콜백에 맞는 대응 res를 구현해주면 된다.
패스포트는 로그인시에 로그인인증을 대행해주는 역할을 한다.
기반엔 OAuth라는 기술이 깔려있음.
사용자: Resource Owner내서버: Client구글 페이스북 같은 서버: Rescource Server, Authorization Server 두가지로 역할에 따라 한번 더 구분 가능하다.사용자입장에서는 사용자의 정보를 내서버에 보관하지 않아도 편리하게 사용할 수 있다.
내 서버 입장에서는 사용자의 정보가 없으니까 정보를 잃는것에 대한 부담을 덜었다.
OAuth는 access Token을 통해 구글이나 페이스북 등의 서버에 사용자가 가지고 있는 특정 권한을 수행할 수 있는 대행자역할을 가능하게 해주는 기능이다.
Federated Identity는 OAuth기반의 기술이다.

Client가 Authorization Server에 권한을 대행받기 위해서는 Authorization Server에 내 서비스 즉 Client가 등록이 되어있어야 한다. 이때 필요한게 바로
ClientID: 공개되도 되는 값 -> 내 서비스라는 것의 식별자Client Secret: 꼭 숨겨야하는 값 -> 내 서비스의 비밀번호같은 값Authorized redirect URIs: https://client/callback -> 리소스서버가 권한을 부여할 때 코드를 내 서비스에 전달해주는데 코드를 전달받을 주소. 따라서 다른 곳에서 요청이 오더라도 무시하고 이 주소로만 코드를 준다.이러한 ClientID, Client Secret는 해당 리소스서버의 앱을 만들면 생성되고 설정같은 곳에서 확인 가능하다. Authorized redirect URIs는 그 해당 앱에 설정같은 곳에 내서비스의 콜백값(물론 내서비스에 라우트 구현이 필요함)을 등록해주는 공간이 있는데 거기에 등록하면 된다.
ClientID, ClientSecret, redirectURL을 가지고 Authorization Server에 권한허용을 요청하면(github에 경우는 Clientsecret없이 요청해도 현재 가능함)
Authorization Server는 Resource Owner에게 이 권한을 이 client에게 허용해줘도 되는지 승인 페이지를 띄운다. 이 페이지에 승인허용을 하게 되면 Authorization Server는 client에게 허용된 권한을 등록하게 된다.
Resource Owner에 의해 client가 특정권한에 대한 승인이 Authorization Server에 되었다면 Authorization Server는 Authorization Code를 callback?code=123123에 형태로 clinet에게 줍니다.
client는 Authorization code와 clientID, clientSecret, Authorized redirect URIs 을 다시 Authorization Server에 전송하면서 나 허용된 client 맞다고 호소합니다. 그럼 Authorization Server는 Authorization Code와 ClientSecret을 확인하며 최종적으로 해당 client에게 승인 해주고 access token 과 refresh token을 줍니다.
client는 이 Access token을 통해 Resource Owner로 부터 승인 받은 권한들을 페이스북이나 깃헙같은 곳에서 제공해준 API API를 통해 Resource Server 요청해서 받고 사용할 수 있습니다.
access token하나만으로 계속 client 와 Resource Server의 통신을 허락해주는건 좀 위험한 방식이다. 따라서 Access token의 수명은 정해져 있다. 만약 다시 Access token을 받기위해서 2~3 과정을 반복하는건 비용이 들기 때문에 refresh token으로 Authorization Server에 다시 Access token을 요청하면 새로운 Access token 과 refresh token을 계속 새로 얻을 수 있다.

공식문서링크에 있던 자료 중 발췌한 자료인데, 위에 이미지는 OAuth 2.0 부분에 동작 방식이다.
A, B 부분이 위에서 설명한 1~4번까지의 과정이다. 이후 access token을 통해 Resource Server와 통신을 하면 되는 것이다. 만약 access token이 만료되면 access token 과 함께 받은 refresh token을 통해 다시 access token 과 refresh token 을 받고 통신을 반복하면 된다.