- 해당 방식은 Client와 Server가 통신할 때마다 Header 에 Id, pw 등의 정보를 포함 시킨 후
통신하는 방식이다. 매 통신마다 해당 정보를 검증하며 위조여부 등을 판단한다.
-> 단점 :
. 해커가 해당 패킷을 탈취 시 중요 정보가 유출된다.
. 매번 인증정보를 확인해야 하며 이는 비효율적이다.
-> 장점 :
. 구현이 쉽다.
2. 서버가 유저 인증 시 특정 세션정보를 활용하는 방법.
- 유저의 로그인 절차 중 해당 정보가 인증된다면 이 유저에 대한 세션ID를 부여한다.
그 후 세션 ID를 Header에 포함시켜 보내면, client는 해당 session id 를 쿠키에 저장한 후
서버와 통신할 때 인증정보가 필요한 경우 header에 포함시킨다.
-> 단점 :
. 이 역시 해커가 탈취 시 중요 정보의 유출 위험이 존재한다.
-> 세션 별 life time 을 설정해서 유효시간을 지정함으로서 탈취된 경우 무효화 될 수 있게 한다.
-> HTTPS를 적용하여 탈취 후 에도 header를 파악하기 어렵게 한다.
. 세션을 저장할 추가적인 비용(DB, memory 등)가 발생한다.
-> 장점 :
. 패킷 탈취 시 해당 session ID로만 구성되어 있으므로 유의미한 정보는 유출되지 않는다.
3. Token 기반 인증방식을 적용한다.(보통은 JSON Web token 사용)
- token 정보를 header에 포함시켜 전달하는 방식이다. jwt의 경우 지정된 암호화 방식으로 tokenize를 진행할 수 있고 이에 대한 SECRET KEY 로 복호화 후 위변조 여부를 판단할 수 있다.
jwt의 경우 Header, payload, verify signature 로 구성되며 header, payload는 누구나 복호화 할 수 있고 verify signature의 경우 SECRET KEY를 알지못하면 복호화 하지 못한다. 따라서 payload에는 중요정보를 포함하면 안된다.
-> 단점 :
. 이 방식 역시 해커가 탈취가능하다.
-> 이 역시, access token에 expire time을 적용하면 피해를 다소 방지할 수 있다.
. payload는 복호화가 가능하기 때문에 넣을 수 있는 data는 한정적이다.
. 서버에서 복호화하는 비용이 발생한다.
-> 장점 :
. session 인증 방식과 크게본다면 동일하지만 볃도의 비용이 발생하진 않는다.(DB 불필요)
일단 주요 원리는 특정 루틴의 호출 시점, 종료시점에서 시간을 측정해서 시간 경과를 측정하는 것이다.
개인적으로 Clock() 함수 혹은 timeGetTime() 함수는 사용해보지 않았기 때문에
QueryPerformanceFrequency / QueryPerformanceCounter 함수와 관련된 내용만 적어보려고 한다.
우선 두 함수 모두 Windows.h 에 포함된 함수이며 각각 CPU의 현재의 연산주기, 연산횟수를 얻어오는데 쓰인다.
[계산주기, 횟수라고 한것은 영어 원문에선 performance-counter라고 되어 있음]
위 두가지를 사용하여 시간을 측정하는 방법은 아래의 순서로 진행된다.
1. 우선 QueryPerformanceFrequency를 통해서 현재 프로그램이 돌아가는 장치의 계산주기를 얻는다.
2. QueryPerformanceCounter 함수를 특정 로직의 앞, 뒤에서 호출하여 start, end 시의 계산 횟수를 구한다.
* 이 때 end-start 를 통해서 특정 로직의 수행시 cpu가 몇번의 계산을 했는지 알 수 있다.[deltaCount]
3. 위의 deltaCount의 값을 계산주기로 나누면 경과한 시간을 알 수 있다.
* 계산주기=[계산횟수/시간] 이기 때문에 경과시간 = deltaCount / (계산횟수 / 단위시간) 이 된다.
그렇다면 C#의 경우는 어떤 방법들이 있을까?
우선 C#에서도 C++에서 사용하는 QueryPerformanceCounter 함수들을 사용하는 방법도 있다.
이 경우, DllImport를 사용하여 QueryPerformanceCounter, QueryPerformanceFrequency를선언하면 된다.
public class QueryPerfCounter
{
[DllImport("KERNEL32")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
private long start;
private long stop;
private long frequency;
double multiplier = 1.0e6; // usecs / sec
public QueryPerfCounter()
{
if (QueryPerformanceFrequency(out frequency) == false)
{
// Frequency not supported
throw new Win32Exception();
}
}
public void Start()
{
QueryPerformanceCounter(out start);
}
public void Stop()
{
QueryPerformanceCounter(out stop);
}
public double Duration(int iterations)
{
return ((((stop - start) * multiplier) / frequency) / iterations);
}
이 방법보다 좀더 간편한 방법으로는 stopwatch를 사용하는 방법이다.
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
}