*출처 코드스테이츠
어떠한 문자열에 '임의의 연산'을 적용하여 다른 문자열로 변환 하는것
모든 값에 대해 해시 값을 계산하는데 오래 걸리지 않아야 한다.
최대한 같은 해시 값을 피해야하며, 모든 값은 고유한 해시 값을 가진다.
아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야 한다.
혹여나 데이터베이스가 뚫려 비밀번호가 노출된다고 하더라도, 해싱된 비밀번호를 다른 사이트에 대입을 해봐도 뚫일일이 낮기 때문에 악용될 여지가 줄어든다.
- 이해를 돕기위한 단순한 암호화의 예
암호화해야 하는 값에 어떤 '별도의 값'을 추가하여 결과를 변형하는 것
암호화만 해놓는다면 해시된 결과가 늘 동일 하기 때문에 해시된 값과 원래 값을 테이블(레인보우 테이블)로 만들어서 decoding 해버리는 문제가 발생 할 수 있다.
원본값에 임의로 약속된 '별도의 문자열'을 추가하여 해시를 진행한다면 기존 해시값과 전혀 다른 해시값이 반환되어서 알고리즘이 만약 노출이 되더라도 원본값을 보호할 수 있는 확률이 더 올라간다.
해싱만 했을경우 : (암호화 하려는 값) => (hash값)
salt를 같이 사용할 경우 : (암호화 하려는 값) + (Salt 값) => (hash) 값
Salt는 유저와 패스워드 별로 유일한 값을 가져야 한다.
사용자 계정을 생성할 때와 비밀번호를 변경할 때 마다 새로운 임의의 Salt를 사용해서 해싱해야 한다.
Salt는 절대 재사용하지 말아야 한다.
Salt는 DB의 유저 테이블에 같이 저장되어야 한다.
*출처:https://blog.webf.zone/ultimate-guide-to-http-cookies-2aa3e083dbae
HTTP는 stateless (무상태성) 인데 어떻게 우리의 정보가 유지가 되는가? 바로 쿠키 덕분이다.
쿠키란? 서버에서 클라이언트에 데이터를 저장하는 방법의 하나
서버가 원한다면 서버는 클라이언트에서 쿠키를 이용하여 데이터를 가져올 수 있다.
쿠키를 이용하는 것은 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고 클라이언트에서 서버로 쿠키를 전송하는 것도 포함
하지만 데이터를 저장한 이후 아무 때나 데이터를 가져올 수 없다. 데이터를 저장한 이후 특정 조건들이 만족하는 경우에만 다시 가져올 수 있다.
그 특정 조건들에 대한 정보는 MDN SetCookie 에 잘나와있다.
이러한 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless 한 인터넷 연결을 Stateful 하게 유지할 수 있다.
하지만 기본적으로는 쿠키는 오랜 시간 동안 유지될 수 있고, 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험하다.이런 인증정보를 탈취하여 서버에 요청을 보낸다면 서버는 누가 요청을 보낸 건지 상관하지 않고 인증된 유저의 요청으로 취급하기 때문에, 개인 유저 정보 같은 민감한 정보에 접근이 가능하다.
사용자가 인증에 성공한 상태를 세션이라한다.
서버와 클라이언트에 각각 필요한 것은?
웹사이트에서 로그인을 유지하기 위한 수단으로 쿠키를 사용하며. 쿠키에는 서버에서 발급한 세션 아이디를 저장
사용자가 만일 정확한 아이디와 비밀번호를 입력했다면, 서버는 인증(Authentication)에 성공했다고 판단할 것이다. 그렇다면, 다음 번에 인증을 필요로 하는 작업을 요청할 경우, 또 로그인 과정을 거쳐야 할까? 서버는 아이디 및 비밀번호의 해시를 이미 알고 있기 때문에, "인증에 성공했음"을 서버가 알고 있다면, 매번 로그인을 할 필요가 없을 것이다.(인증에 따라 리소스의 접근 권한(Authorization) 이 달라진다는 뜻이다)
서버가 Client에 유일하고 암호화된 ID를 부여한다.
중요한 데이터는 서버에서 관리한다.
로그아웃 기능은 어떻게 구현 할수 있을까?
이러한 세션을 대신 관리해주는 모듈중에 express-session 이 있다.
Session의 단점
클라이언트가 토큰을 가지고 있다면 보통의 다른(돈을 내지 않은) 유저들과는 다르게 서버에서 제공하는 다양한, 더 프리미엄한 기능을 요청할수 있다.
토큰은 유저 정보를 암호화한 상태로 담을 수 있고, 암호화 했기 때문에 클라이언트에 담을 수 있다.
보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용합니다. 클라이언트가 처음 인증을 받게 될 때(로그인시), access, refresh token 두가지를 다 받지만, 실제로 권한을 얻는데 사용하는 토큰은 access token이다.
권한을 부여 받는데엔 access token만 가지고 있으면 된다. 하지만 access token을 만약 악의적인 유저가 얻어냈다면 어떻게 될까? 이 악의적인 유저는 자신이 00유저인것 마냥 서버에 여러가지 요청을 보낼 수 있게 된다(만약 돈과 관련된 문제라면 큰일이 날 수 있다).
그렇기 때문에 access token에는 비교적 짧은 유효기간 을 주어 탈취 되더라도 오랫동안 사용할 수 없도록 하는것이 좋다. Access token의 유효기간이 만료된다면 refresh token을 사용하여 새로운 access token을 발급 받습니다. 이때, 유저는 다시 로그인 할 필요가 없다
유저의 편의보다 정보를 지키는 것이 더 중요한 웹사이트들은 refresh token을 사용하지 않는 곳이 많다. 세상에 완벽한 보안은 없기 때문에 각 방법들의 장단점을 참고하며 필요에 맞게 사용하는 것이 좋다.
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "someInformation",
"name": "phillip",
"iat": 151623391
}
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
*출처 코드스테이츠
인증을 위한 표준 프로토콜의 한 종류로 보안 된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공(Authorization)하는 프로세스를 단순화하는 프로토콜 중 한 방법(소셜로그인)
1) 유저 입장에서 생각해보자면, 우리는 웹 상에서 굉장히 많은 서비스들을 이용하고 있고 각각의 서비스들을 이용하기 위해서는 회원가입 절차가 필요한 경우가 많다. 그 서비스별로 ID와 Password를 다 기억하는 것은 매우 귀찮은 일이기때문에 OAuth 를 활용한다면 자주 사용하고 중요한 서비스들(예를 들어 google, github, facebook) 의 ID와 Password만 기억해 놓고 해당 서비스들을 통해서 소셜 로그인을 할 수 있게 되므로 매우 편리해진다.
2) 보안상의 이점도 있다. 검증되지 않은 App에서 OAuth를 사용하여 로그인한다면, 유저의 민감한 정보가 App에 노출될 일이 없고 인증 권한에 대한 허가를 미리 유저에게 구해야 되기 때문에 더 안전하게 사용할 수 있게 된다.
Resource Owner: 액세스 중인 리소스의 유저, 만약 나의 네이버 계정을 이용하여 어떠한 App에 로그인을 하게될 경우, 이 때 Resource Owner는 내가 될것이다.
Client: Resource owner를 대신하여 보호된 리소스에 액세스하는 응용프로그램
Resource server : client의 요청을 수락하고 응답할 수 있는 서버입니다.
Authorization server : Resource server가 액세스 토큰을 발급받는 서버입니다. 즉 클라이언트 및 리소스 소유자를 성공적으로 인증한 후 액세스 토큰을 발급하는 서버를 말합니다.
Authorization grant : 클라이언트가 액세스 토큰을 얻을 때 사용하는 자격 증명의 유형.
Authorization code : access token을 발급받기 전에 필요한 code 입니다. client ID로 이 code를 받아온 후, client secret과 code를 이용해 Access token 을 받아온다.
Access token : 보호된 리소스에 액세스하는 데 사용되는 credentials. Authorization code와 client secret을 이용해 받아온 이 Access token으로 이제 resource server에 접근을 할 수 있다.
Scope : scope는 토큰의 권한을 정의한다. 주어진 액세스 토큰을 사용하여 액세스할 수 있는 리소스의 범위.
*모든출처 코드스테이츠