bcrypt
: 비밀번호 해싱(hash) 알고리즘으로, 보안을 강화하기 위해 사용됨. 비밀번호를 직접 저장하는 대신 해시된 값을 저장하여, 데이터 유출 시에도 원래 비밀번호를 유추하기 어렵게 만듦.
특징
1. 가변적인 해상 라운드 : bcrypt는 해싱을 여러 번 반복하여 해시 값을 생성함. 라운드 수를 늘릴수록 연산이 복잡해지고, 해킹 시도를 더욱 어렵게 만듦.
2. 솔트(salt / 소금 아님) 추가 : 솔트는 비밀번호 해싱 과정에 추가되는 임의의 데이터로, 같은 비밀번호라도 다른 해시값을 생성하여 무차별 대입 공격을 방어함.
3. 비밀번호 검증 : bcrypt는 저장된 해시 값과 입력된 비밀번호의 해시 값을 비교하여 일치 여부를 확인함.
해싱(Hashing)
: 임의 길이의 데이터를 고정 길이의 해시 값으로 변환하는 과정. 이때 사용되는 함수가 해시 함수(hash function)임. 해시 함수는 입력 데이터(보통 텍스트, 파일, 또는 문자열)를 받아서 고정된 크기의 고유한 데이터 출력(해시 값 또는 해시 코드)을 생성함.
특징
1: 고정된 길이의 출력 : 입력 데이터의 크기와 상관없이 해시 함수는 항상 고정된 길이의 해시 값을 반환함.
2. 비가역성 : 해시 함수의 중요한 특성 중 하나는 비가역성임. 즉, 해시 값을 가지고 원래 데이터를 역으로 추측하거나 복원하는 것은 거의 불가능함. 이 때문에 해싱은 비밀번호 저장이나 데이터 무결성 검증에 유용함.
3. 빠른 연산 속도 : 해시 함수는 입력 데이터를 매우 빠르게 처리할 수 있어야 함. 이 속성 덕분에 해싱은 대량의 데이터 처리와 검색에서 효율적임.
용도
1: 비밀번호 저장 : 데이터베이서에 비밀번호를 평문으로 저장하는 것은 매우 위험함. 해싱을 통해 비밀번호를 고정 길이의 해시 값으로 변환해 저장하면, 데이터베이스가 해킹되더라도 원래 비밀번호를 쉽게 알 수 없음.
2. 데이터 무결성 검증 : 파일 전송이나 데이터 백업 시 해시 값을 생성해두고, 나중에 동일한 해시 값을 다시 계산해 비교함으로써 데이터가 손상되거나 변조되지 않았는지 확인할 수 있음.
3. 데이터 검색 및 인덱싱 : 해시 테이블은 키-값 쌍을 매우 효율적으로 저장하고 검색하는 자료구조로, 데이터베이스나 캐시 시스템에서 많이 사용됨.
bcrypt와 해싱
bcrypt는 단순한 해싱 알고리즘과는 달리, 해싱 과정에 솔트(salt)를 추가하고 여러 번의 해싱 라운드를 적용하여 보안을 덩욱 강화함. 솔트는 해시 충돌 방지와 비밀번호 해시의 유일성을 보장하기 위해 사용됨. 동일한 비밀번호라도 서로 다른 솔트를 사용하면 전혀 다른 해시 값이 생성됨.
비밀번호 검증
: bcrypt를 사용하면 해싱된 비밀번호와 사용자 입력 비밀번호를 비교할 때도 안전하게 비교할 수 있음. 이는 입력된 비밀번호를 동일한 방법으로 해싱하여 저장된 해시 값과 일치하는지 확인하는 방식으로 이루어짐.
비가역성
: 해시 함수의 중요한 특성 중 하나로, 입력 데이터를 해시 함수에 통과시켜 해시 값을 얻는 것은 쉽지만, 그 해시 값을 이용해 원래의 입력 데이터를 역으로 계산하는 것은 불가능하거나 매우 어렵다는 의미.
특징
한 방향성 : 해시 함수는 데이터를 한 방향으로만 처리할 수 있음. 즉, 원본 데이터에서 해시 값을 생성하는 것은 가능하지만, 생성된 해시 값만으로 원본 데이터를 복원할 수는 없음.
중요성
1. 비밀번호 저장 : 비가역성 덕분에 해시 함수는 비밀번호 저장에 매우 유용함. 예를 들어, 비밀번호를 해시로 변환하여 데이터베이스에 저장하면, 데이터베이스가 해킹되더라도 해시 값만으로는 원래의 비밀번호를 알아낼 수 없음.
2. 데이터 무결성 보장 : 파일이나 메시지를 전송할 때, 데이터를 해시화하여 보내면 수신자는 동일한 해시 값을 계산해 원본 데이터가 변조되지 않았는지 확인할 수 있음. 비가역성 덕분에 공격자는 해시 값을 보고 원본 데이터를 재구성하여 변조하는 것이 매우 어려움.
비가역성을 통한 보안 강화
1. 솔트와 해싱 : 비가역성을 강화하기 위해 솔트라는 무작위 데이터를 추가하여 해싱함. 솔트는 동일한 입력 값에도 다른 해시 값을 생성하게 만들어, 비가역성을 더욱 강화함.
2. 암호학적 해시 함수 : 비가역성을 가진 해시 함수는 암호학적 해시 함수라고 불리며, 주로 보안이 중요한 응용 프로그램에서 사용됨. 대표적인 암호학적 해시 함수로는 SHA-256, SHA-3, bcrypt 등이 있음.
한계
1. 충돌 공격 : 이론적으로는 두 개의 서로 다른 입력 값이 동일한 해시 값을 생성하는 경우가 있을 수 있음. 이를 해시 충돌이라 하며, 암호학적 해시 함수는 이러한 충돌이 발생할 확률을 극도로 낮추어 비가역성을 유지함.
2. 무차별 대입 공격 (Brute Force Attack) : 비가역성은 해시 값만으로 원본을 직접 복원할 수 없게 하지만, 공격자가 모든 가능한 입력 값을 해싱해보는 방식으로 원본을 찾아낼 수도 있음. 이런 공격을 방지하기 위해 bcrypt 같은 알고리즘은 해시 생성 속도를 인위적으로 느리게 만들어 공격을 어렵게 함.
useStat와 async, await의 차이
useStae : React 훅으로, 컴포넌트의 상태를 관리하는데 사용됨. 상태 값과 해당 값을 변경할 수 있는 함수를 반환하며, 컴포넌트의 상태가 변경될 때 컴포넌트를 다시 렌더링함.
async : Javascript에서 비동기 작업을 간편하게 처리하기 위한 구문임. async 함수가 비동기 작업을 수행함을 명시하며 자동으로 promise를 반환함.
await : async 함수 내부에서 사용되며, promise가 해결될 때까지 함수의 사용을 일시중지 시킴.
차이점
1. 작동 방식
: useState는 react의 상태관리 훅이며, 값의 변경을 감지하고 컴포넌트를 재렌더링하지만, async / await는 비동기 작업을 순차적으로 처리하고, 비동기 함수의 결과를 기다릴 때까지 사용됨.
2. 사용 영역
: useState는 react 컴포넌트에서 상태를 관리하는데 사용되지만, async / await는 비동기 코드를 처리하는 모든 Javascript 코드에서 사용됨.
JavScript와 TypeScript의 차이점
Javascript
: 웹 개발에서 널리 사용되는 프로그래밍 언어로, 동적이며 타입 검사 없이 코드를 작성할 수 있음.
특징
1. 동적 타이핑 : 변수의 타입을 미리 지정하지 않고, 런타임에 결정됨.
2. 유연성 : 코드 작성이 간단하지만, 런타임 오류 발생 가능성이 높음.
Typescript
: javascript에 정적 타입 검사를 추가한 상위 언어로 , 컴파일 타임에 오류를 잡아낼 수 있음.
특징
1. 정적 타이핑 : 변수와 함수의 타입을 미리 정의하여, 코드 안정성과 유지보수성을 높임.
2 . 향상된 IDE(통합 개발 환경) 지원: 코드 자동 완성, 타입 추론, 코드 리팩토링(기존 코드의 동작을 변경하지 않으면서 코드의 구조를 개선하여 가독성, 유지보수성 등을 향상시키는 작업) 등이 개선됨.
3. Javascript 호환성 : Typescript는 Javascript로 컴파일 되며, 기존 Javascript 코드와 함께 사용할 수 있음.
차이점
1. 타입 시스템 : Javascript는 동적 타이핑을 사용하는 반면, Typescript는 정적 타이핑을 사용함.
2. 개발 경험 : Typescript는 더 나은 개발자 경험을 제공하며, 특히 대규모 프로젝트에서 오류를 줄이고 코드 품질을 유지하는데 도움이 됨.
✏ IDE (통합 개발 환경)
:Integrated Development Environment의 약자로, 소프트웨어 개발을 위한 통합 도구 모음.
코드 편집기, 컴파일러 또는 인터프리터, 디버거, 빌드 자동화 도구 등을 하나의 통합된 환겨에서 제공하여 개발자들이 효율적으로 작업할 수 있게 함.
주요 기능
1. 코드 작성 및 편집 : 코드 편집기에서 다양한 언어를 지원하며, 구문 강조(syntax highlighting) 및 자동 완성 기능을 제공.
2. 디버깅 : 코드에서 오류를 찾고 수정할 수 있는 디버거를 포함함.
3. 버전 관리 :Git 같은 버전 관리 시스템과 통합되어, 코드의 변경 사항을 추적하고 협업할 수 있게 해줌.
ex. Visual Studio Code, IntelliJ IDEA, Eclipse, PyCharm
✏ 코드 리팩토링 (Code Refactoring)
: 기존 코드의 동작을 변경하지 않으면서, 코드의 구조를 개선하여 가독성, 유지보수성, 성능을 향상 시키는 작업
목적
1. 가독성 향상 : 코드를 더 읽기 쉽고 이해하기 쉽게 만듦.
2. 유지보수성 개선 : 코드의 복잡도를 줄여 수정이나 추가 작업이 쉽게 이루어질 수 있도록 함.
3. 버그 감소 : 복잡한 코드를 단순화 하여 잠재적인 오류를 줄임.
ex. 함수 이름 변경, 코드 중복 제거, 메서드 추출
✏ 타입 추론
: 컴파일러가 명시적으로 타입을 선언하지 않아도, 변수나 함수의 타입을 자동으로 추론하는 기능. TypeScript와 같은 정적 타입 언어에서 많이 사용됨.
장점
1. 코드 간결화 : 개발자가 명시적으로 타입을 선언하지 않아도 되므로, 코드를 더 간결하게 작성할 수 있음.
2. 오류 방지 : 컴파일러가 타입을 추론해주므로, 잘못된 타입 사용을 방지할 수 있음.
ex.
let num = 10; // 컴파일러가 num의 타입을 자동으로 number로 추론
✏ 로깅 (Logging)
: 애플리케이션의 동작이나 상태를 기록하는 작업. 로깅을 통해 시스템의 동작을 추적하고, 오류 발생 시 원인을 분석할 수 있음.
용도
1. 디버깅 : 프로그램이 어떻게 실행되고 있는지 확인하기 위해 로깅을 사용함.
2. 모니터링 : 시스템의 상태를 모니터링하고, 예기치 않은 동작이나 오류를 감지함.
3. 감사 로그 : 중요한 작업이나 이벤트의 기록을 남겨, 나중에 참조할 수 있게 함.
ex.
console.log("User logged in:", userId);
React와 Redux, Next.js의 차이
React
: 사용자 인터페이스(UI)를 구축하기 위한 Javascript 라이브러리임. 컴포넌트를 기반으로 UI를 구성하고, 상태 관리를 통해 동적인 웹 애플리케이션을 만듦.
특징
1. 컴포넌트 기반 : UI를 재사용 가능한 컴포넌트로 분할하여 관리함.
2. 상태 관리 : useState, useReducer 등을 통해 상태를 관리함.
3. 가상 DOM : 변경 사항을 최소화 하여 성능을 최적화 함.
Redux
: 애플리케이션의 상태를 전역적으로 관리하기 위한 상태 관리 라이브러리임. React와 함께 자주 사용됨.
특징
1. 전역 상태 관리 : 모든 컴포넌트가 접근할 수 있는 단일 상태 저장소를 유지함.
2. 액션과 리듀서 : 상태 변경은 액션(action)을 통해 수행되며, 리듀서(reducer)가 새로운 상태를 반환함.
3. 미들웨어 : 비동기 작업이나 로깅 같은 추가 기능을 위해 미들웨어를 사용할 수 있음.
✏ 미들웨어 (Middleware)
: 애플리케이션의 요청(Request)과 응답(Response) 사이에 위치하여, 요청을 처리하거나 응답을 조작하는데 사용되는 함수. 주로 서버 측 애플리케이션에서 사용됨.
용도
1. 요청 처리 : 인증, 권한 검사, 데이터 변환, 로깅 등을 수행.
2. 응답 처리 : 응답 데이터의 변환, 캐싱, 압축 등을 수행
3. 라우팅 : 요청이 올바른 핸들러에 도달하도록 경로를 설정함.
Next.js
: React를 기반으로 한 프레임워크로, 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)를 지원함. SEO 최적화와 빠른 페이지 로딩을 위한 기능을 제공함.
특징
1. 서버 사이드 렌더링(SSR) : 초기 페이지를 서버에서 렌더링하여, SEO와 초기 로딩 속도를 개선함.
2. 정적 사이트 생성(SSG) : 빌드 타임에 HTML 파일을 생성하여 빠른 로딩을 지원함.
3. 파일 기반 라우팅 : 페이지 파일을 생성하는 것만으로 자동으로 라우팅이 설정됨.
✏ SEO (검색 엔진 최적화)
: Search Engine Optimization의 약자로, 웹사이트나 웹페이지를 검색 엔진 결과에서 더 높은 순위에 노출시키기 위한 다양한 최적화 기법을 말함.
목적
1. 트래픽 증가 : 검색 엔진에서 더 많은 사용자가 웹사이트를 발견할 수 있도록 하여, 트래픽을 늘림.
2. 가시성 향상 : 특정 키워드에 대해 웹 사이트의 가시성을 높여, 관련 검색에서 상위에 노출되도록 함.
주요 요소
1. 키워드 최적화 : 사용자가 검색할 가능성이 높은 키워드를 페이지 콘텐츠에 적절히 포함시킴.
2. 메타 태그 : 제목, 설명 등 메타 정보를 최적화하여 검색 엔진이 페이지를 올바르게 이해할 수 있도록 함.
3. 콘텐츠 품질 : 유익하고 가치있는 콘텐츠를 제공하여, 사용자의 만족도를 높임.
✏ SEO 최적화
: SEO의 여러 요소들을 체계적으로 적용하여, 검색 엔진에서 웹사이트 순위를 높이기 위한 과정을 의미.
방법
1. 모바일 친화성 : 모바일 사용자에게도 최적화 된 경험을 제공하기 위해 반응형 디자인을 적용함.
2. 페이지 속도 개선 : 페이지 로딩 시간을 단축하여 사용자 경험을 개선하고, 검색 엔진에서의 평가를 높임.
3. 백링크 구축 : 신뢰할 수 있는 다른 웹사이트로부터의 링크(백링크)를 얻어, 사이트의 권위를 높임.
React → Redux에서의 개선점
1. 전역 상태 관리의 일관성
: Redux는 애플리케이션의 전역 상태를 단일 스토어에서 관리함. 이로 인해 상태의 흐름이 일관되고 예측 가능하게 됨. 모든 상태 변경은 액션(Action)을 통해 이루지며, 이 액션이 리듀서(Reducer)를 통해 상태를 업데이트 함. 이 구조 덕분에 상태 변경이 투명하게 이루어지고, 디버깅이 용이함.
반면, React는 useState와 useReducer는 각각의 컴포넌트에 국한된 상태 관리를 제공하며, 전역 상태 관리에는 적합하지 않을 수 있음. 여러 컴포넌트 간에 상태를 공유해야하는 경우, React의 상태 관리 도구만으로는 복잡성이 증가할 수 있음.
2. 미들웨어 지원
: Redux는 강력한 미들웨어 생태계를 가지고 있음. Redux Thunk나 Redux Saga와 같은 미들웨어를 사용하면, 비동기 작업을 처리하거나 로깅, 분석, API 호출 등의 부가적인 작업을 상태 관리와 함께 통합적으로 처리할 수 있음. 이는 복잡한 애플리케이션에서 특히 유용함.
React의 상태 관리만으로는 이러한 미들웨어 기능을 자연스럽게 구현하기 어려울 수 있음. useEffect를 사용해 비동기 작업을 처리할 수는 있지만 Redux가 제공하는 만큼의 확장성과 일관성은 없음.
3. 상태의 불변성 및 데이터 흐름
: Redux는 상태가 불변성을 유지하도록 설계되어 있음. 모든 상태 변경은 새로운 상태 객체를 반환하도록 강제됨. 이러한 불변성 원칙은 복잡한 상태 구조를 가진 애플리케이션에서 상태의 추적과 버그 예방에 도움을 줌.
React의 useState와 useReducer도 불변성을 유지할 수 있도록 코딩할 수는 있지만, 이는 개발자의 책임에 달려있음. 복잡한 상태를 관리할 때, Redux처럼 체계적인 방식이 없는 경우 상태 관리가 혼란스러워질 수 있음.
4. 대규모 애플리케이션에서의 확장성
: Redux는 대규모 애플리케이션에서 확장성이 뛰어남. 전역 상태가 증가하더라도 Redux의 아키텍처는 상태 관리가 체계적으로 이루어지도록 도와줌. 또한, 여러 개발자들이 협업할 때 상태 관리와 관련된 규칙이 명확하게 정의되어 있어 작업이 수월함.
반면, React의 상태 관리 도구만으로는 규모가 커질수록 상태 관리가 복잡해지고 관리하기 어려워질 수 있음.
React → Next. js에서의 개선점
1. SSR과 SSG 지원
: Next.js는 React의 클라이언트 사이드 렌더링(CSR) 외에도 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 지원하여 SEO와 성능을 크게 개선함.
2. 파일 기반 라우팅
: Next.js는 라우팅을 자동화하여, React의 수동 라이팅 설정보다 개발을 단순화 함.
3. 데이터 페칭
: Next.js는 getStaticProps, getServerSideProps와 같은 함수로 데이터 패칭을 간소화 하여, React의 데이터 패칭 로직보다 효율적이고 체계적인 방식을 제공함.
✏ 데이터 패칭
: 애플리케이션이 외부 소스 (ex. API, 데이터베이스, 파일 등)에서 데이터를 요청하고 받아오는 과정을 말함. 주로 웹 애플리케이션에서 서버로부터 데이터를 가져와 사용자에게 보여줄 때 사용됨.