(1) 
porm.xml에 라이브러리 추가
<ScribeJava>
==> 웹서비스를 제작할 때 다양한 SNS 서비스의 OAuth를 이용하는 경우가 많은데
이것들을 하나로 처리할 수 있는 통합 라이브러리입니다.


<!-- Naver  -->
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>2.8.1</version>
</dependency>    

servlet-context.xml 에 beans에 naver Bo 추가
<beans:bean id="naverLoginBO" class="test.domain.NaverLoginBO" />


(2) NaverLoginBO.java 클래스 생성

package main.naver.com;

import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
 
 
public class NaverLoginBO {

    // 발급받은 client id;
    private String CLIENT_ID = "ID";
    
    // 발급받은 client Secret
    private String CLIENT_SECRET="SECRET";

    // 로그인성공시 리턴될 URL
    private String REDIRECT_URI="http://localhost:8080/mytest/member/oauth_naver";
    
    // 세션 유효값검증용 체크용
    private String SESSION_STATE = "oauth_state"; 

    // 프로필 조회 API URL
    private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";

    public String getAuthorizationUrl(HttpSession session) {
        // 세션 유효성 검증을 위하여 난수를 생성
        String state = generateRandomString();
        // 생성한 난수 값을 session에 저장
        setSession(session, state);

        // Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성
        OAuth20Service oauthService = new ServiceBuilder()
                .apiKey(CLIENT_ID)
                .apiSecret(CLIENT_SECRET)
                .callback(REDIRECT_URI)
                .state(state) //앞서 생성한 난수값을 인증 URL생성시 사용함
                .build(NaverLoginApi.instance());
        return oauthService.getAuthorizationUrl();
    }

    public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException {

        // Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인
        String sessionState = getSession(session);
        if (StringUtils.pathEquals(sessionState, state)) {

            OAuth20Service oauthService = new ServiceBuilder()
                    .apiKey(CLIENT_ID)
                    .apiSecret(CLIENT_SECRET)
                    .callback(REDIRECT_URI)
                    .state(state)
                    .build(NaverLoginApi.instance());

            // Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득
            OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
            return accessToken;
        }
        return null;
    }

    // 세션 유효성 검증을 위한 난수 생성기
    private String generateRandomString() {
        return UUID.randomUUID().toString();
    }

    // http session에 데이터 저장
    private void setSession(HttpSession session, String state) {
        session.setAttribute(SESSION_STATE, state);
    }

    // http session에서 데이터 가져오기
    private String getSession(HttpSession session) {
        return (String) session.getAttribute(SESSION_STATE);
    }

    // Access Token을 이용하여 네이버 사용자 프로필 API를 호출
    public String getUserProfile(HttpSession session, OAuth2AccessToken oauthToken) throws IOException {

        OAuth20Service oauthService = new ServiceBuilder()
                .apiKey(CLIENT_ID)
                .apiSecret(CLIENT_SECRET)
                .callback(REDIRECT_URI).build(NaverLoginApi.instance());

        OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService);
        oauthService.signRequest(oauthToken, request);
        Response response = request.send();
        return response.getBody();
    }
}

(3) NaverLoginApi 클래스 생성

package main.naver.com;

import com.github.scribejava.core.builder.api.DefaultApi20;

public class NaverLoginApi extends DefaultApi20 {
     protected NaverLoginApi(){
    }

    private static class InstanceHolder{
        private static final NaverLoginApi INSTANCE = new NaverLoginApi();
    }


    public static NaverLoginApi instance(){
        return InstanceHolder.INSTANCE;
    }

    @Override
    public String getAccessTokenEndpoint() {
        return "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code";
    }

    @Override
    protected String getAuthorizationBaseUrl() {
        return "https://nid.naver.com/oauth2.0/authorize";
    }
}

(4) 컨트롤러

@RequestMapping("/navergo")
	public @ResponseBody String getNaverAuthUrl(HttpSession session) throws Exception {
	    String reqUrl = (new NaverLoginBO()).getAuthorizationUrl(session);
	    return reqUrl;
	}
	 

	// 네이버 연동정보 조회
	@RequestMapping(value = "/oauth_naver")
	public String oauthNaver(HttpServletRequest request, HttpServletResponse response) throws Exception {
	    JsonParser parser = new JsonParser();
	    Gson gson = new Gson();

	    HttpSession session = request.getSession();
	    String code = request.getParameter("code");
	    String state = request.getParameter("state");
	    String error = request.getParameter("error");
	    
	    // 로그인 팝업창에서 취소버튼 눌렀을경우
	    if ( error != null ){
	        if(error.equals("access_denied")){
	            return "redirect:/login";
	        }
	    }

	    OAuth2AccessToken oauthToken;
	    oauthToken = new NaverLoginBO().getAccessToken(session, code, state);
	    //로그인 사용자 정보를 읽어온다.
	    String loginInfo = new NaverLoginBO().getUserProfile(session, oauthToken);
	    System.out.println(loginInfo);
	    // JSON 형태로 변환
	    Object obj = parser.parse(loginInfo);
	    JsonObject jsonObj = (JsonObject)obj;
	    JsonObject callbackResponse = (JsonObject) jsonObj.get("response");
	    String naverUniqueNo = callbackResponse.get("id").toString();
	    
	    
	    if (naverUniqueNo != null && !naverUniqueNo.equals("")) {
	    	System.out.println(naverUniqueNo);
	    	
	        /** 
	            TO DO : 리턴받은 naverUniqueNo 해당하는 회원정보 조회 후 로그인 처리 후 메인으로 이동
	        */
	    	return "/member/login";
	    // 네이버 정보조회 실패
	    } else {
	        throw new Exception("네이버 정보조회에 실패했습니다.");
	    }

	}

(5)view 네이버로그인 JS

<script>
	$("#naverLoginGo").on("click",function(){
	    $.ajax({
	        url: 'navergo',
	        type: 'get',
	        success: function(res){
		    	 location.href = res;
		    },
			error : function(req, status, error){
                console.log("에러");
                console.log(req.responseText);
        	}
	    
		});
	    })
</script>

'API 적용해보기' 카테고리의 다른 글

스프링에 썸머노트 적용해보기  (0) 2022.01.16

썸머노트 실행 + 이미지 별도처리 JS

//썸머노트 실행 함수
        function notesummer(){
            //썸머노트 실행
            $('#summernote').summernote({
            lang:"ko-KR",
            placeholder: '내용을 입력해주세요',
            tabsize: 2,
            width : 1200,
            height: 600,
            toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'underline', 'clear']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['table', ['table']],
                ['insert', ['link', 'picture', 'video']],
                ['view', ['fullscreen', 'codeview', 'help']]
            ],
            callbacks : { 
                //onImageUpload = 이미지 업로드시 작동하는 콜백함수
                onImageUpload : function(files, editor, welEditable) {
            // 파일 업로드(다중업로드를 위해 반복문 사용)
                for (var i = files.length - 1; i >= 0; i--) {
                        uploadSummernoteImageFile(files[i],
                        this);
                        }
                }
            }//end callbacks 
            });
            // 이미지 업로드시 ajax로 파일 업로드를 하고 성공 후 파일 경로를 return받음
            function uploadSummernoteImageFile(file, editor) {
            data = new FormData();
            data.append("file", file);
            $.ajax({
                url : "summernoteImage",
                data : data,
                type : "POST",
                dataType : 'JSON',
                contentType : false,
                processData : false,
                success : function(data) {
                    //항상 업로드된 파일의 url이 있어야 한다.
                    $(editor).summernote('insertImage', contextPath+data.url);
                }
            });
            } 
        }

 

 

이미지 처리 컨트롤러 코드

	//썸머노트 이미지처리 ajax
	@PostMapping("summernoteImage")
	//썸머노트 이미지 처리
	public String insertFormData2(
			@RequestParam(value="file", required=false) MultipartFile file,HttpSession session
			) {
		Gson gson = new Gson();
		Map<String, String> map = new HashMap<String, String>();
		// 2) 웹 접근 경로(webPath) , 서버 저장 경로 (serverPath)
		String WebPath = "/resources/images/summernoteImages/"; //DB에 저장되는 경로
		String serverPath = session.getServletContext().getRealPath(WebPath);
		String originalFileName=file.getOriginalFilename();
		String extension = originalFileName.substring(originalFileName.lastIndexOf("."));
		String savedFileName = UUID.randomUUID() + extension;	//저장될 파일 명
		File targetFile = new File(serverPath + savedFileName);	
		try {
			InputStream fileStream = file.getInputStream();
			FileUtils.copyInputStreamToFile(fileStream, targetFile);	//파일 저장
			// contextroot + resources + 저장할 내부 폴더명
			map.put("url", WebPath+savedFileName);
			map.put("responseCode", "success");
		} catch (IOException e) {
			FileUtils.deleteQuietly(targetFile);	//저장된 파일 삭제
			map.put("responseCode", "error");
			e.printStackTrace();
		}
		return gson.toJson(map);
	}

'API 적용해보기' 카테고리의 다른 글

스프링에 네이버로그인 적용해보기  (0) 2022.01.16

+ Recent posts