MkAuthToken을 개발하긴 했는데,, Node와는 너무 다른 그것이기 때문에 살짝 사용법을 정립하기가 어려웠다.

JWT 특성상 서버에서는 단지 토큰 생성, 검증만 수행하기 때문에 모든 관리를 클라이언트가 해야하는 부담이 있고, MkWeb은 프론트 개발자가 최대한 이러한 활동에 집중하지 않게 하자는 목표가 있었기 때문에 더욱 그러했다.

하지만, JWT를 사용하기로 결정했고, 따라서 "클라이언트에서 이를 관리할 필요가 있다." 고 결론을 내렸다.

그럼 어떻게 Client에서 사용하게 할 것인가를 고민해 봤는데, html에서 지원하는 cookie를 이용하여 저장할 예정이다.


먼저 토큰을 생성하자.

JWT를 저장하려면 우선 JWT가 생성되어 있어야 한다. 로그인과 같은 행위를 통해 JWT를 발급받아고, 해당 토큰 값을 내가 알고 있어야 한다.

서버를 배포할 때 설정한 mkweb.auth.uri를 통해 (ajax를 사용하든 어떤 방법이 되었든...) token을 생성하자. (이 때, 모든 처리는 method: POST, Cotent-Type: application/json 이어야 한다.)

$("#login").click(function(){
	$.ajax({
		type : "POST", 
		url : "/auth/login",
		dataType : "json",
		data : {
        	"user_id" : $("#userid").val(),
			"user_pw" : $("#userpw").val()
		},
		success : function(rd){
			if(rd.token){
				...
			}
		}     
	});
});

토큰생성에 성공했다면, ajax결과로 다음과 같은 형식의 데이터를 전달받는다.

{"code": 200, "token":"your_token"}

이 후, document.cookie를 통해 토큰 값을 저장한다.

$("#login").click(function(){
	$.ajax({
		...
		success : function(rd){
			if(rd.token){
				document.cookie = createCookie(token);
			}
		}     
	});
});

let __MK_TOKEN_LIFETIME__ = 600;
let __MK_TOKEN_NAME__ = 'mkauthtoken';

function createCookie(token){
    var date = new Date();
    date.setTime(date.getTime() + __MK_TOKEN_LIFETIME__ * 1000);
    let cookieInfo = __MK_TOKEN_NAME__ + '=' + token + ';expires=' + date.toUTCString() + ';path=/';
    return cookieInfo;
}

토큰의 사용

토큰을 구하고, 삭제하는 방법은 다음과 같다.

function getToken(cookieInfo){
    var value = document.cookie.match('(^|;) ?' + __MK_TOKEN_NAME__ + '=([^;]*)(;|$)');
    return value ? value[2] : null;
}

function removeTokenCookie(cookieInfo) {
    var date = new Date();
    document.cookie = __MK_TOKEN_NAME__ + "= ; expires=" + date.toUTCString() + "; path=/";
}

주의사항

let __MK_TOKEN_LIFETIME__ = 600;
let __MK_TOKEN_NAME__ = 'mkauthtoken';

자바스크립트에 작성된 위 두 옵션은 MkWeb.conf에 설정된 mkweb.auth.lifetime, mkweb.auth.controller.name 두 속성과 일치하는 값을 가져야 한다.


꼭 JSP / HTML일 필요는 없다!

React 등 프론트 개발을 위해 다른 프레임워크 / 라이브러리를 사용해도 서버를 MkWeb을 이용할 때, 단지 프론트에서 토큰을 잘 가지고 있기만 하면 된다! 나는 프론트 개발은 HTML + Javascript + Css 밖에 안해봤기 때문에,, ㅎㅎ

MkWeb 프레임워크에 로그인과 관련된 Authorization 기능을 제공하기 위해 JWT를 사용하려고 결정했다.

 

[Authorization] 프레임워크 권한 설정 / JWT for MkWeb

MKWeb에 로그인 기능을 구현할 때, Session/Cookie를 이용하여 구현할지, 구현한다면 어떤 방식으로 현재의 MKWeb과 결합할 수 있을 지 많은 고민을 했다. 로그인이라는 것 자체가 꽤 민감한 부분인 만

dev-whoan.xyz

MkWeb의 특징 때문에, Controller마다 다른 Authorize 인증과 관련하여 어떻게 하면 좋을까 고민했다.

생각해 보니 큰 고민이 아니었던게, MkWeb의 Controller들에 각 인증관련 기능을 추가해주면 됐다.


첫 번째, Page Controllers

앞선 글에서 말한것 처럼, 페이지에 크게 "Authorize"와 관련된 속성을 추가해 줄 것이고, 그 값은 다음과 같다.

1. no: 이 페이지는 누구나 볼 수 있다.
2. part: 이 페이지에 종속된 컨트롤러 중 권한이 필요한 것이 있다.
3. yes: 이 페이지를 보려면 반드시 권한이 인증되어야 한다.

페이지 컨트롤러로 접속시켜주는 녀석은 결국 MkDispatcher기 때문에, MkDispatcher의 제일 마지막 부분에 ConnectionChecker를 이용한 getPageAuthorization을 통해 권한 인증 여부를 확인했다. 해당 함수는 0, 1, 2 (각각 no, part, yes에 대응된다.)의 값을 리턴해주고, 2가 아니라면, 페이지를 보여주면 된다.


두 번째, SQL Controllers

SQL Controller가 제일 필요한 곳은 바로 MkWeb의 Custom Tag인 tagSEL다.

tagSEL의 최상단에 HttpServletRequest 객체를 이용하여 authorization이 설정되었는지 보고, 설정되어 있지 않다면 Unauthorized 401을 반환해주면 끝이다.


세 번째, API Controllers

SQL Controller와 마찬가지로, API Controllers는 최초에 Authorization을 확인한 뒤, 검증되지 않았다면 취소시키면 된다. 와! API를 만들 때 가장 코드를 많이 먹던 녀석이 바로 parameter중 어딘가에 포함되어있을 key를 찾는 것이었는데, authorization을 확인함으로써 정말 간단해졌다! 오예!

음... 사실 지난주 까지 쉬기로 했는데 이번주에 작은누나가 휴가라..ㅋㅋ이번주까지 널널하게 할거다! 

이거 올리면 0.0.9로 버전 올려야징

MKWeb에 로그인 기능을 구현할 때, Session/Cookie를 이용하여 구현할지, 구현한다면 어떤 방식으로 현재의 MKWeb과 결합할 수 있을 지 많은 고민을 했다.

로그인이라는 것 자체가 꽤 민감한 부분인 만큼 해당 부분을 구현하기 위해서 많은 공부가 필요했고 21년도 1학기가 시작되었기 때문에 그러기에는 좀 바빴다.

특히 20년 8월~ 21년 7월까지 진행한(아직 진행중인) 오픈배지 프로젝트에서도 사용자의 로그인을 구현해야 했는데, 이를 통해 해당 고민을 해결할 수 있었다.

일단 세션/쿠키 방식이 아닌 Json Web Token을 이용하여 사용자 인증을 구현하려 한다.

쉽게 설명하자면, Json 형태의 어떤 정보를 Token화 하여서 서버와 클라이언트가 주고받는 방식이다.

사용자가 로그인을 시도하면, 서버에서는 아이디와 패스워드를 확인하고, 로그인에 성공했다면 사용자의 정보를 이용하여 Payload를 만든다.

또한 JWT에 사용되는 암호화 방식과 토큰정보를 사용하고있는 Header가 존재하고, JWT에 대한 서명인 Signature가 있다.

이 세 파트는 연결되어서 xxxx.yyyyyy.zzzzz와 같은 형태로 존재하게 된다.

header와 payload는 base64URL로 encoding 되기 때문에 사용자의 비밀번호 등 민감한 정보를 절대 포함해서는 안된다.


JWT를 사용하기 위해 잠깐 생각해본 방법은 다음과 같다.

컨트롤러에 대하여 상위 옵션으로 "auth"에 대하여 [ all, part, none ]과 같은 설정을 할 수 있고, all의 경우 해당 페이지(혹은 컨트롤러)는 로그인과 같은 사용자 인증이 필수인 경우.

part는 컨트롤러의 일부 서비스는 사용자 인증이 필요한 경우.

none은 컨트롤러는 사용자 인증 없이 이용 가능한 경우로 정하면 어떨까 싶다.

오늘부로 내 방학 계획표 중 노는날이 끝나고 (...) 바쁜 일상이 시작되었으니, 이번주는 조금 널널하게 하기 위해 브레인스토밍 형식으로 진행하고 있기 때문에, 사실 이 방향으로 fix 한다는 보장은 없다.

그래도 나중에 돌아봤을 때, 꽤 좋은 기록물이 되지 않을까 싶어 오늘도 글을 쓰지만..

 

'웹서버 > MKWeb' 카테고리의 다른 글

[RESTful API] MkWeb RestAPI 메모장  (0) 2021.07.31
[Authorization] MkWeb JWT를 이용한 Authorization 설계  (0) 2021.07.21
MkWeb의 Controller  (0) 2021.03.29
MkWeb이란 무엇인가?  (0) 2021.03.29
MkWeb을 시작하게 된 이유  (0) 2021.03.29

+ Recent posts