2024. 7. 30. 18:09ㆍSpringboot-React
스프링 부트쪽 작성
application.properties
server.port=9011
#com.kh로 시작하는 패키지에 문제가 생기면 볼 수 있도록 확인하는 코드
logging.level.com.kh=debug
server.servlet.session.tracking-modes=cookie
#코드의 수정이 있을 때 자동으로 새로고침
spring.devtools.livereload.enabled=true
#코드의 변경이 있을 때 자동으로 다시 시작. mapper.xml 수정 해도 새로고침 하지 않고 바로 적용
spring.devtools.restart.enabled=true
#자동 캐시 지우기
spring.thymeleaf.cache=false
#네이버 로그인을 위한 키 작성하기
naver.client-id = 클라이언트키
naver.client-secret = 클라이언트 시크릿 키
#node.js에서는 로컬호스트3000이었지만 스프링부트는 9010이므로 맞춰서 작성
naver.redirect-uri = http://localhost:9011/api/naverLogin
naver.state = RANDOM_STATE
OAuthController.java
package com.kh.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import jakarta.servlet.http.HttpSession;
// NaverLogin을 한 후에 로그인한 내용을 리액트에서 볼 수 있도록 NaverLoginController 파일을 수정
// NaverLoginController.java 주소 (api url) 충돌을 막기 위해 @RequestMapping("/api")를 제거
@RestController
public class OAuthController {
@Value("${naver.client-id}")
private String clientId;
@Value("${naver.client-secret}")
private String clientSecret;
@Value("${naver.redirect-uri}")
private String redirectUri;
@Value("${naver.state}")
private String state;
@GetMapping("/naverLogin")
public String naverLogin() {
String api_url = "https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + state;
return "<a href='"+ api_url + "'><img height='50' src='http://static.nid.naver.com/oauth/small_g_in.PNG'/></a>";
}
@GetMapping("/callback")
public String callback(@RequestParam String code, @RequestParam String state, HttpSession session) {
String api_url = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id="
+ clientId + "&client_secret=" + clientSecret + "&redirect_uri=" + redirectUri + "&code=" + code + "&state=" + state;
RestTemplate restTemplate = new RestTemplate();
// 앞의 값은 키 이름이기 때문에 String
// 키 이름에 담긴 값은 String이라고 확정지을 수 없으므로 Object
Map<String, Object> responseResult = restTemplate.getForObject(api_url, Map.class);
System.out.println("Token response : " + responseResult);
// token 인증받은 값을 가져오는 데 Bearer access_token 사용
// 가져온 token 데이터를 문자열로 변환, 글자처럼 사용
String accessToken = (String) responseResult.get("access_token");
//네이버 개발자 문서에 access_token으로 로그인 허영된 값을 가져가라고 써있음
String 유저정보가담긴Url = "https://openapi.naver.com/v1/nid/me";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + accessToken);
HttpEntity<String> entity = new HttpEntity<>("", headers);
//HttpEntity = 응답, 요청 모두 있음. 상세한 기능은 없음. ** ResponseEntity, RequestEntity = 각자 상세 기능 보유
ResponseEntity<Map> userInfoRes = restTemplate.exchange(유저정보가담긴Url, HttpMethod.GET, entity, Map.class);
Map<String, Object> userInfo = userInfoRes.getBody();
session.setAttribute("userInfo", userInfo); //session에 로그인 정보를 담음
return "redirect:";
}
//가져온 네이버 정보를 리액트로 전달할 GetMapping
@GetMapping("/userInfo")
//HttpSession - > import jakarta O - 신버전 / javax X - 구버전
public Map<String, Object> userInfo(HttpSession session) {
//httpSession을 Map으로 형변환
Map<String, Object> userInfo = (Map<String, Object>)session.getAttribute("userInfo");
return userInfo;
}
}
** HttpHeaders에 인증에 대한 값을 Bearer로 가져오기
Bearer : 인증을 위해 서버에 제공되는 보안 토큰. 사용자가 인증을 받고 나서 API 요청을 할 때 사용
ex) 네이버에 로그인을 하고 나면 사용자에게 로그인 됐음을 인증하는 토큰을 발급
추후 네이버에 로그인 된 기록을 가지고 어떠한 요청을 할 때 헤더에
Authorization : Bearer{} 작성하고 요청을 해야함
* Bearer = 소유자
Authorization : Bearer{}
= 권한 부여 : 권한을 가진 사람{"권한을 가지고 있는 번호"}
NaverLoginController.java
package com.kh.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
//리액트와 스프링 프레임워크 연동을 위한 컨트롤러
//OAuthController와 api url 주소가 동일해서 나타나는 충돌을 막기 위해 모든 url 앞에 api가 붙도록 설정
@RestController
@RequestMapping("/api")
public class NaverLoginController {
@Value("${naver.client-id}")
private String clientId; // = YMEPgkqT9p7r23tbgj3h
@Value("${naver.client-secret}")
private String clientSecret; // = VaKtGlGPXp
@Value("${naver.redirect-uri}")
private String redirectUri; // = http://localhost:9010/naverLogin
@Value("${naver.state}")
private String state; // = RANDOM_STATE
@GetMapping("/naverLogin") // api/naverLogin
public String naverLogin() {
String api_url = "https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + state;
return "<a href='"+ api_url + "'><img height='50' src='http://static.nid.naver.com/oauth/small_g_in.PNG'/></a>";
}
//url에 {}=변수명 표시가 없으면 @RequestParam이나 @RequestBody
//url에 {}=변수명 표시가 있으면 @PathVariable. {}안에 있는 변수명에 값을 집어넣음
@GetMapping("/callback")
public String callback(@RequestParam String code, @RequestParam String state) {
String api_url = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id="
+ clientId + "&client_secret=" + clientSecret + "&redirect_uri=" + redirectUri + "&code=" + code + "&state=" + state;
//RestTemplate = http 메서드(get,post,put,delete)를 통해 데이터를 json 형식으로 데이터를 처리
RestTemplate rt = new RestTemplate();
//api_url 주소로 응답받은 결과를 String(문자열)으로 가져와서 사용
String responseResult = rt.getForObject(api_url, String.class);
return responseResult;
}
}
** @Value : application.properties나 config.properties에 작성한 키 이름과 키에 담긴 값을 가져옴
** 네이버에서 로그인을 성공했을 때 받는 값
String api_url = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id="
+ clientId + "&client_secret=" + clientSecret + "&redirect_uri=" + redirectUri + "&code=" + code + "&state=" + state;
1. clientId = 어디 회사에 들어왔는가
2. clientSecret = 회사에 들어오기 위한 비밀번호
3. redirectUri = 들어오기 위한 심사를 완료했으면 나갈 위치로 전달
4. code = 네이버로부터 무사히 들어왔다는 인증코드를 받음
5. state = CSRF 공격을 방지하기 위해 사용
** @GetMapping("/naverLogin") // api/naverLogin
public String naverLogin() {
String api_url = "https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + state;
return "<a href='"+ api_url + "'><img height='50' src='http://static.nid.naver.com/oauth/small_g_in.PNG'/></a>";
}
↓ ↓ ↓
app.get('/naverLogin', function (req, res) {
api_url = 'https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=' + client_id + '&redirect_uri=' + redirectURI + '&state=' + state;
res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
res.end("</a href='"+ api_url + "'>http://static.nid.naver.com/oauth/small_g_in.PNG'/>");
});
와 맞추는 getmapping
실행 화면
'Springboot-React' 카테고리의 다른 글
이미지 여러개 올리기 2 (0) | 2024.08.06 |
---|---|
이미지 여러개 올리기 1 (0) | 2024.08.06 |
네이버 로그인 1 (0) | 2024.07.30 |
mysql-react-springboot 연결하기 2 (0) | 2024.07.26 |
mysql-react-springboot 연결하기 1 (0) | 2024.07.26 |