Java로 OpenID Consumer 서비스 구현하기 #1 : OpenID란?
Java로 OpenID Consumer 서비스 구현하기 #2 : OpenID4Java로 인증요청하기
Java로 OpenID Consumer 서비스 구현하기 #3 : OpenID4Java로 인증확인하기
이제 간단하게 인증을 요청하고 인증확인을 구현하였는데 실제 서비스를 하려면 추가정보를 받아야 한다. 로그인처리를 하려면 추가정보가 필요하다. 오른아이디를 통해서 회원가입 처리를 하려고 해도 그렇고 아이디야 당연히 넘어오지만 이름, 닉네임, 전화번호등등의 정보를 받아와야 한다.
openid4java에 들어있는 SampleConsumer를 보면 아래와 같은 코드들이 있다.(앞에서 만든 SampleConsumer말고...)
FetchRequest fetch = FetchRequest.createFetchRequest();이 코드가 추가정보를 요청하는 코드인데 이 코드는 Attribute Exchange 스펙을 이용하는 코드이다. 스펙에 이름에서 알 수 있듯이 추가적인 정보를 교환하는 스펙이다. 나도 스펙들을 대충 보고 당연히 이걸 이용한다고 생각하고 열심히 삽질을 했는데 어찌된 일인지 정보를 받아올 수 있었다. 의외로 추가정보를 Attribute Exchange를 이용하는 것이 아니라 Simple Registration Extension 스펙(영문스펙)을 이용한다. Simple Registration Extension을 이용해서 유저의 추가정보를 받아 올 수가 있다.(Attribute Exchange가 왜 안되는지는 나도 잘 모르겠다. 안된다기 보다는 내가 못하는 거겠지만... 이래서 스펙을 볼 줄 알아야 하는건데....)
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
authReq.addExtension(fetch);
어쨌든 Simple Registration Extension를 이용해서 정보를 요청하자.
SRegRequest sreq = SRegRequest.createFetchRequest();
sreq.addAttribute("email", true);
sreq.addAttribute("nickname", true);
sreq.addAttribute("fullname", true);
sreq.addAttribute("dob", true);
sreq.addAttribute("gender", true);
authReq.addExtension(sreq);
일단 인증을 요청할 때 추가정보도 같이 요청해야 하기 때문에 authRequest 메서드안에
AuthRequest authReq = manager.authenticate(discovered, returnToUrl, trustRoot);
아래쪽에 위의 코드를 추가해 준다. (SRegRequest를 AuthRequest객체에 추가해 주어야 하므로..) 그리고 SReqRequest를 사용하려면 org.openid4java.message.sreg.SRegRequest를 import 해주어야 한다. 이렇게만 하고 다시 실행을 하고 인증을 요청하면
위의 사진처럼 OP측에서 사용자의 추가정보를 넘겨주는 것을 사용자에게 보여준다. 당연히 End-User는 여기서 정보를 변경해 줄 수가 있다. End-User가 승인을 하면 OP는 인증정보와 함께 요청한 추가정보를 같이 담아서 RP측이 받을 수 있도록 해준다. 요청하는 정보는 Simple Registration Extension의 스펙을 확인하면 되고 당연히 OP측에거 가지고 있는 정보만 요청해서 받을수 있다.
추가정보를 요청하고 OP가 정보를 넘겨주었으니 그럼 이제 받아보자.
if (verified != null) {
AuthSuccess authSuccess = (AuthSuccess) verification.getAuthResponse();
if (authSuccess.hasExtension(SRegMessage.OPENID_NS_SREG))
{
MessageExtension ext = authSuccess.getExtension(SRegMessage.OPENID_NS_SREG);
if (ext instanceof SRegResponse)
{
SRegResponse sregResp = (SRegResponse) ext;
String nickName = sregResp.getAttributeValue("nickname");
String email = sregResp.getAttributeValue("email");
String dob = sregResp.getAttributeValue("dob");
String gender = sregResp.getAttributeValue("gender");
httpReq.setAttribute("nickName", nickName);
httpReq.setAttribute("email", email);
httpReq.setAttribute("dob", dob);
httpReq.setAttribute("gender", gender);
}
}
return verified; // success
}
기존 코드의 verifyResponse 메서드 안에 있는 if (verified != null) {} 의 부분을 위의 코드로 바꾸어준다. 앞에서는Simple Registration Extension의 정보를 확인하는 부분이 없었기 때문에...(다시 한번 말하지만 소스의 세세한 부분은 이해하지 못하고 있다.) 간단히 설명하자면 SRegMessage가 있는지 확인하고 있으면 SRegResponse로 받아서 각 정보를 받아온다. 나는 이 메서드를 호출한 JSP파일에서 다시 정보를 받아야 하기 때문에 verifyResponse를 호출할 때 파라미터로 넘겨준 Request에 각 정보를 다시 심어주는 방식을 택했다.
위의 코드를 사용하려면 org.openid4java.message.sreg.SRegMessage 와 org.openid4java.message.sreg.SRegResponse 를 import 해주어야 한다.
이제 JSP에서 받아오자.
// resultOpenid.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<% request.setCharacterEncoding("utf-8"); %>
<% response.setContentType("text/html; charset=utf-8"); %>
<%@ page import="org.openid4java.discovery.Identifier" %>
<%@ page import="kr.test.openid.SampleConsumer" %>
<%
SampleConsumer sc = (SampleConsumer)application.getAttribute("cm");
Identifier ver = sc.verifyResponse(request);
if (ver != null) {
out.println(ver.getIdentifier() + "님 환영합니다.<br>");
out.println("닉네임 : " + request.getAttribute("nickName") + "<br>");
out.println("이메일 : " + request.getAttribute("email") + "<br>");
out.println("생년월일 : " + request.getAttribute("dob") + "<br>");
out.println("성별 : " + request.getAttribute("gender") + "<br>");
} else {
out.println("로그인에 실패하였습니다.");
}
%>
다음에 다시 OpenID를 구현할 때는 좀더 수준 높게 해볼 수 있게 되기를 바라면서.. ^^
오예 님 사랑합니다 ㅠㅠ 뉴비 살려주셔서 감사감사 ㅎㅎ
ㅎㅎㅎ 도움되셨다니 다행이네요.
myopenid에는 정보등록은 안되어 있으셔서 아쉽네요.
좋은 정보 감사합니다^^
예.. 방문해 주셔서 감사합니다 ^^