-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1 feat: 소셜 로그인과 Spring Security6 적용
- Loading branch information
Showing
19 changed files
with
576 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
src/main/java/com/ns/solve/Auth/kakao/KakaoController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.ns.solve.Auth.kakao; | ||
|
||
import com.ns.solve.Auth.naver.NaverService; | ||
import com.ns.solve.Domain.dto.MessageEntity; | ||
import com.ns.solve.Service.MembershipService; | ||
import com.ns.solve.Utils.JwtToken; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.ui.Model; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.servlet.view.RedirectView; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("kakao") | ||
public class KakaoController { | ||
|
||
private final KakaoService kakaoService; | ||
private final NaverService naverService; | ||
private final MembershipService membershipService; | ||
|
||
@RequestMapping(value="/", method= RequestMethod.GET) | ||
public String login(Model model) { | ||
model.addAttribute("kakaoUrl", kakaoService.getKakaoLogin()); | ||
model.addAttribute("naverUrl", naverService.getNaverLogin()); | ||
return "index"; | ||
} | ||
|
||
@GetMapping("/login") | ||
public RedirectView login(){ | ||
return new RedirectView(kakaoService.getKakaoLogin()); | ||
} | ||
|
||
@GetMapping("/callback") | ||
public ResponseEntity<MessageEntity> callback(HttpServletRequest request) throws Exception { | ||
KakaoDTO kakaoInfo = kakaoService.getKakaoInfo(request.getParameter("code")); | ||
|
||
Long id = kakaoInfo.getId(); | ||
JwtToken token = membershipService.LoginMembership(id); | ||
|
||
if (token!=null) | ||
return ResponseEntity.ok() | ||
.body(new MessageEntity("Success ", token)); | ||
else return ResponseEntity.ok() | ||
.body(new MessageEntity("Fail ","token is empty.")); // empty시 register시켜야함. | ||
} | ||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.ns.solve.Auth.kakao; | ||
|
||
import lombok.Builder; | ||
import lombok.Data; | ||
|
||
@Builder | ||
@Data | ||
public class KakaoDTO { | ||
|
||
private long id; | ||
private String email; | ||
private String nickname; | ||
|
||
} |
116 changes: 116 additions & 0 deletions
116
src/main/java/com/ns/solve/Auth/kakao/KakaoService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package com.ns.solve.Auth.kakao; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.parser.JSONParser; | ||
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.stereotype.Service; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
|
||
@Service | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class KakaoService { | ||
|
||
@Value("${KAKAO_CLIENT_ID}") | ||
private String KAKAO_CLIENT_ID; | ||
|
||
@Value("${KAKAO_CLIENT_SECRET}") | ||
private String KAKAO_CLIENT_SECRET; | ||
|
||
@Value("${KAKAO_REDIRECT_URL}") | ||
private String KAKAO_REDIRECT_URL; | ||
|
||
private final static String KAKAO_AUTH_URI = "https://kauth.kakao.com"; | ||
private final static String KAKAO_API_URI = "https://kapi.kakao.com"; | ||
|
||
public String getKakaoLogin() { | ||
return KAKAO_AUTH_URI + "/oauth/authorize" | ||
+ "?client_id=" + KAKAO_CLIENT_ID | ||
+ "&redirect_uri=" + KAKAO_REDIRECT_URL | ||
+ "&response_type=code"; | ||
} | ||
|
||
public KakaoDTO getKakaoInfo(String code) throws Exception { | ||
if (code == null) throw new Exception("Failed get authorization code"); | ||
|
||
String accessToken = ""; | ||
String refreshToken = ""; | ||
|
||
try { | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add("Content-type", "application/x-www-form-urlencoded"); | ||
|
||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); | ||
params.add("grant_type" , "authorization_code"); | ||
params.add("client_id" , KAKAO_CLIENT_ID); | ||
params.add("client_secret", KAKAO_CLIENT_SECRET); | ||
params.add("code" , code); | ||
params.add("redirect_uri" , KAKAO_REDIRECT_URL); | ||
|
||
RestTemplate restTemplate = new RestTemplate(); | ||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers); | ||
|
||
ResponseEntity<String> response = restTemplate.exchange( | ||
KAKAO_AUTH_URI + "/oauth/token", | ||
HttpMethod.POST, | ||
httpEntity, | ||
String.class | ||
); | ||
|
||
JSONParser jsonParser = new JSONParser(); | ||
JSONObject jsonObj = (JSONObject) jsonParser.parse(response.getBody()); | ||
|
||
accessToken = (String) jsonObj.get("access_token"); | ||
refreshToken = (String) jsonObj.get("refresh_token"); | ||
} catch (Exception e) { | ||
throw new Exception("API call failed"); | ||
} | ||
|
||
return getUserInfoWithToken(accessToken); | ||
} | ||
|
||
private KakaoDTO getUserInfoWithToken(String accessToken) throws Exception { | ||
//HttpHeader 생성 | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add("Authorization", "Bearer " + accessToken); | ||
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); | ||
|
||
//HttpHeader 담기 | ||
RestTemplate rt = new RestTemplate(); | ||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(headers); | ||
ResponseEntity<String> response = rt.exchange( | ||
KAKAO_API_URI + "/v2/user/me", | ||
HttpMethod.POST, | ||
httpEntity, | ||
String.class | ||
); | ||
|
||
log.info("Received json : "+ response.getBody()); | ||
//Response 데이터 파싱 | ||
JSONParser jsonParser = new JSONParser(); | ||
JSONObject jsonObj = (JSONObject) jsonParser.parse(response.getBody()); | ||
JSONObject account = (JSONObject) jsonObj.get("kakao_account"); | ||
JSONObject profile = (JSONObject) account.get("profile"); | ||
|
||
long id = (long) jsonObj.get("id"); | ||
String email = String.valueOf(account.get("email")); | ||
String nickname = String.valueOf(profile.get("nickname")); | ||
|
||
return KakaoDTO.builder() | ||
.id(id) | ||
.email(email) | ||
.nickname(nickname).build(); | ||
} | ||
|
||
|
||
|
||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/ns/solve/Auth/naver/NaverController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.ns.solve.Auth.naver; | ||
|
||
import com.ns.solve.Domain.dto.MessageEntity; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("naver") | ||
public class NaverController { | ||
|
||
private final NaverService naverService; | ||
|
||
@GetMapping("/callback") | ||
public ResponseEntity<MessageEntity> callback(HttpServletRequest request) throws Exception { | ||
NaverDTO naverInfo = naverService.getNaverInfo(request.getParameter("code")); | ||
|
||
return ResponseEntity.ok() | ||
.body(new MessageEntity("Success", naverInfo)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.ns.solve.Auth.naver; | ||
import lombok.Builder; | ||
import lombok.Data; | ||
|
||
@Builder | ||
@Data | ||
public class NaverDTO { | ||
|
||
private String id; | ||
private String email; | ||
private String name; | ||
|
||
} |
107 changes: 107 additions & 0 deletions
107
src/main/java/com/ns/solve/Auth/naver/NaverService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package com.ns.solve.Auth.naver; | ||
|
||
import org.json.simple.JSONObject; | ||
import org.json.simple.parser.JSONParser; | ||
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.stereotype.Service; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
@Service | ||
public class NaverService { | ||
|
||
@Value("${NAVER_CLIENT_ID}") | ||
private String NAVER_CLIENT_ID; | ||
|
||
@Value("${NAVER_CLIENT_SECRET}") | ||
private String NAVER_CLIENT_SECRET; | ||
|
||
@Value("${NAVER_REDIRECT_URL}") | ||
private String NAVER_REDIRECT_URL; | ||
|
||
private final static String NAVER_AUTH_URI = "https://nid.naver.com"; | ||
private final static String NAVER_API_URI = "https://openapi.naver.com"; | ||
|
||
public String getNaverLogin() { | ||
return NAVER_AUTH_URI + "/oauth2.0/authorize" | ||
+ "?client_id=" + NAVER_CLIENT_ID | ||
+ "&redirect_uri=" + NAVER_REDIRECT_URL | ||
+ "&response_type=code"; | ||
} | ||
|
||
public NaverDTO getNaverInfo(String code) throws Exception { | ||
if (code == null) throw new Exception("Failed get authorization code"); | ||
|
||
String accessToken = ""; | ||
String refreshToken = ""; | ||
|
||
try { | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add("Content-type", "application/x-www-form-urlencoded"); | ||
|
||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); | ||
params.add("grant_type" , "authorization_code"); | ||
params.add("client_id" , NAVER_CLIENT_ID); | ||
params.add("client_secret", NAVER_CLIENT_SECRET); | ||
params.add("code" , code); | ||
params.add("redirect_uri" , NAVER_REDIRECT_URL); | ||
|
||
RestTemplate restTemplate = new RestTemplate(); | ||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers); | ||
|
||
ResponseEntity<String> response = restTemplate.exchange( | ||
NAVER_AUTH_URI + "/oauth2.0/token", | ||
HttpMethod.POST, | ||
httpEntity, | ||
String.class | ||
); | ||
|
||
JSONParser jsonParser = new JSONParser(); | ||
JSONObject jsonObj = (JSONObject) jsonParser.parse(response.getBody()); | ||
|
||
accessToken = (String) jsonObj.get("access_token"); | ||
refreshToken = (String) jsonObj.get("refresh_token"); | ||
} catch (Exception e) { | ||
throw new Exception("API call failed"); | ||
} | ||
|
||
return getUserInfoWithToken(accessToken); | ||
} | ||
|
||
private NaverDTO getUserInfoWithToken(String accessToken) throws Exception { | ||
//HttpHeader 생성 | ||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add("Authorization", "Bearer " + accessToken); | ||
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); | ||
|
||
//HttpHeader 담기 | ||
RestTemplate rt = new RestTemplate(); | ||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(headers); | ||
ResponseEntity<String> response = rt.exchange( | ||
NAVER_API_URI + "/v1/nid/me", | ||
HttpMethod.POST, | ||
httpEntity, | ||
String.class | ||
); | ||
|
||
//Response 데이터 파싱 | ||
JSONParser jsonParser = new JSONParser(); | ||
JSONObject jsonObj = (JSONObject) jsonParser.parse(response.getBody()); | ||
JSONObject account = (JSONObject) jsonObj.get("response"); | ||
|
||
String id = String.valueOf(account.get("id")); | ||
String email = String.valueOf(account.get("email")); | ||
String name = String.valueOf(account.get("name")); | ||
|
||
return NaverDTO.builder() | ||
.id(id) | ||
.email(email) | ||
.name(name).build(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.ns.solve.Config; | ||
|
||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
import jakarta.persistence.EntityManager; | ||
import jakarta.persistence.PersistenceContext; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class QuerydslConfig { | ||
|
||
@PersistenceContext | ||
private EntityManager entityManager; | ||
|
||
@Bean | ||
public JPAQueryFactory jpaQueryFactory() { | ||
return new JPAQueryFactory(entityManager); | ||
} | ||
} |
Oops, something went wrong.