유저 정보에는 ID / Name / Email / ImageUrl 총 4가지의 정보를 다루겠습니다.
하지만 소셜 로그인 API 종류에 따라 각각 다른 이름으로 값을 넘겨줍니다.
따라서 각각 다른 방법으로 값을 추출해야 합니다. OAuth2UserInfo 추상클래스를 상속받아서 각각의 소셜 로그인에 해당하는 UserInfo 클래스를 작성해 보겠습니다.
컬럼명 | Github | ||
---|---|---|---|
id | sub | id (숫자) | id |
name | name | name | name |
imageUrl | picture | avatar_url | picture.data.url |
import java.util.Map;
public abstract class OAuth2UserInfo {
protected Map<String, Object> attributes;
public OAuth2UserInfo(Map<String, Object> attributes) {
this.attributes = attributes;
}
public Map<String, Object> getAttributes() {
return attributes;
}
public abstract String getId();
public abstract String getName();
public abstract String getEmail();
public abstract String getImageUrl();
}
import com.example.rest.security.oauth2.userinfo.OAuth2UserInfo;
import java.util.Map;
public class GoogleOAuth2UserInfo extends OAuth2UserInfo {
public GoogleOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes);
}
@Override
public String getId() {
return (String) attributes.get("sub");
}
@Override
public String getName() {
return (String) attributes.get("name");
}
@Override
public String getEmail() {
return (String) attributes.get("email");
}
@Override
public String getImageUrl() {
return (String) attributes.get("picture");
}
}
import com.example.rest.security.oauth2.userinfo.OAuth2UserInfo;
import java.util.Map;
public class GithubOAuth2UserInfo extends OAuth2UserInfo {
public GithubOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes);
}
@Override
public String getId() {
return ((Integer)attributes.get("id")).toString();
}
@Override
public String getName() {
return (String) attributes.get("name");
}
@Override
public String getEmail() {
return (String) attributes.get("email");
}
@Override
public String getImageUrl() {
return (String) attributes.get("avatar_url");
}
}
import com.example.rest.security.oauth2.userinfo.OAuth2UserInfo;
import java.util.Map;
public class FacebookOAuth2UserInfo extends OAuth2UserInfo {
public FacebookOAuth2UserInfo(Map<String, Object> attributes) {
super(attributes);
}
@Override
public String getId() {
return (String) attributes.get("id");
}
@Override
public String getName() {
return (String) attributes.get("name");
}
@Override
public String getEmail() {
return (String) attributes.get("email");
}
@Override
public String getImageUrl() {
// 페이스북 이미지 URL > picture:{data:{url:""}}
if(attributes.containsKey("picture")){
Map<String, Object> pictureObj = (Map<String, Object>) attributes.get("picture");
if(pictureObj.containsKey("data")){
Map<String, Object> dataObj = (Map<String, Object>) attributes.get("data");
if(dataObj.containsKey("url")){
return (String) dataObj.get("url");
}
}
}
return null;
}
}
import com.example.rest.model.AuthProvider;
import com.example.rest.security.oauth2.userinfo.social.FacebookOAuth2UserInfo;
import com.example.rest.security.oauth2.userinfo.social.GithubOAuth2UserInfo;
import com.example.rest.security.oauth2.userinfo.social.GoogleOAuth2UserInfo;
import java.util.Map;
public class OAuth2UserInfoFactory {
public static OAuth2UserInfo getOAuth2UserInfo(String registrationId, Map<String, Object> attributes) {
if(registrationId.equalsIgnoreCase(AuthProvider.google.toString())) {
return new GoogleOAuth2UserInfo(attributes);
} else if (registrationId.equalsIgnoreCase(AuthProvider.facebook.toString())) {
return new FacebookOAuth2UserInfo(attributes);
} else if (registrationId.equalsIgnoreCase(AuthProvider.github.toString())) {
return new GithubOAuth2UserInfo(attributes);
} else {
throw new OAuth2AuthenticationProcessingException("Sorry! Login with " + registrationId + " is not supported yet.");
}
}
}
import org.springframework.security.core.AuthenticationException;
public class OAuth2AuthenticationProcessingException extends AuthenticationException {
public OAuth2AuthenticationProcessingException(String msg, Throwable t) {
super(msg, t);
}
public OAuth2AuthenticationProcessingException(String msg) {
super(msg);
}
}