Skip to content

Commit

Permalink
๐Ÿฅ•Feat #23: [OAuth2] ์†Œ์…œ ๋กœ๊ทธ์ธ
Browse files Browse the repository at this point in the history
  • Loading branch information
DDonghyeo committed Jul 24, 2023
1 parent 81dd903 commit 00a376f
Show file tree
Hide file tree
Showing 15 changed files with 451 additions and 8 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ dependencies {
testImplementation 'org.springframework.security:spring-security-test'


//jwt
implementation 'io.jsonwebtoken:jjwt:0.9.1'


}

tasks.named('test') {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/umc/DongnaeFriend/config/JwtConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.umc.DongnaeFriend.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JwtConfig {

@Value("${jwt.secret-key}")
public static String SECRET_KEY;

}
33 changes: 33 additions & 0 deletions src/main/java/com/umc/DongnaeFriend/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.umc.DongnaeFriend.config;

import com.umc.DongnaeFriend.security.JwtTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private JwtTokenFilter jwtTokenFilter;


@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/user/login").permitAll() // ์ธ์ฆ ์—†์ด ์ ‘๊ทผ ํ—ˆ์šฉํ•˜๋Š” URL
.antMatchers("/user/reissuance").permitAll() // ์ธ์ฆ ์—†์ด ์ ‘๊ทผ ํ—ˆ์šฉํ•˜๋Š” URL
.anyRequest().authenticated(); // ๊ทธ ์™ธ์˜ URL์€ ์ธ์ฆ ํ•„์š”
http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
}

// ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋Š” ์ด์ „ ์˜ˆ์ œ์™€ ๋™์ผ
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.umc.DongnaeFriend.domain.dongnae.service.DongnaeBoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.naming.AuthenticationException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.umc.DongnaeFriend.domain.user.contorller;

import com.umc.DongnaeFriend.domain.user.dto.UserDto;
import com.umc.DongnaeFriend.domain.user.service.KakaoService;
import com.umc.DongnaeFriend.domain.user.service.UserService;
import com.umc.DongnaeFriend.global.exception.CustomException;
import com.umc.DongnaeFriend.global.exception.ErrorCode;
import com.umc.DongnaeFriend.global.util.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;

@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
KakaoService kakaoService;

@Autowired
UserService userService;

JwtTokenProvider jwtTokenProvider;

/**
* ์œ ์ € ๋กœ๊ทธ์ธ / ํšŒ์›๊ฐ€์ž…
* ์ธ์ฆ ์ ˆ์ฐจ
*/
@PostMapping("/login")
public ResponseEntity<?> userLogin(@RequestBody UserDto.Request request) {
try {
//์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
HashMap<String, Object> userInfo = kakaoService.getUserInfo(request.getAccessToken());

//์‚ฌ์šฉ์ž ํ™•์ธ ๊ธฐ์กด ํšŒ์› -> ๋„˜์–ด๊ฐ€๊ณ , ์—†๋Š” ํšŒ์› -> ํšŒ์›๊ฐ€์ž…
userService.userValidation(userInfo);

//ํ† ํฐ ์ƒ์„ฑ
String access_token = jwtTokenProvider.createAccessToken((Long) userInfo.get("usreId"));

return ResponseEntity.ok(access_token);

} catch (IOException e) {
throw new CustomException(ErrorCode.INVALID_AUTH_TOKEN);
}
}

@PostMapping("/user/reissuance")
public ResponseEntity<?> reiussnaceToken(String access_oto)



}
40 changes: 40 additions & 0 deletions src/main/java/com/umc/DongnaeFriend/domain/user/dto/UserDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.umc.DongnaeFriend.domain.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

public class UserDto {

@Getter
@AllArgsConstructor
public static class Request {

String accessToken;

String type;

}

@Getter
@AllArgsConstructor
public static class Response {

String accessToken;

String refreshToken;

}

@Getter
@AllArgsConstructor
public static class SignUpDto {

String nickName;

String email;

Long kakaoId;

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class User extends BaseTimeEntity {
private Long id;

@ManyToOne(fetch = LAZY)
@JoinColumn(name = "dongnae_id", nullable = false)
@JoinColumn(name = "dongnae_id")
private Dongnae dongnae;

@Column(nullable = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.DongnaeFriend.domain.user.repository;

import com.umc.DongnaeFriend.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findById(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.umc.DongnaeFriend.domain.user.service;


import java.io.IOException;
import java.util.HashMap;

public interface KakaoService {

HashMap<String, Object> getUserInfo(String access_Token) throws IOException;
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.umc.DongnaeFriend.domain.user.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

@Service
public class KakaoServiceimpl implements KakaoService {

// @Autowired
// public IACDao dao;

@SuppressWarnings("unchecked")
@Override
public HashMap<String, Object> getUserInfo(String access_Token) throws IOException {
// ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์ •๋ณด
HashMap<String, Object> userInfo = new HashMap<String, Object>();


//------kakao GET ์š”์ฒญ------
String reqURL = "https://kapi.kakao.com/v2/user/me";
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + access_Token);

int responseCode = conn.getResponseCode();
System.out.println("responseCode : " + responseCode);

BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

String line = "";
String result = "";

while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("response body : " + result);
System.out.println("result type" + result.getClass().getName()); // java.lang.String

// jackson objectmapper ๊ฐ์ฒด ์ƒ์„ฑ
ObjectMapper objectMapper = new ObjectMapper();
// JSON String -> Map
Map<String, Object> jsonMap = objectMapper.readValue(result, new TypeReference<Map<String, Object>>() {
});

System.out.println(jsonMap.get("properties"));

Map<String, Object> properties = (Map<String, Object>) jsonMap.get("properties");
Map<String, Object> kakao_account = (Map<String, Object>) jsonMap.get("kakao_account");

// System.out.println(properties.get("nickname"));
// System.out.println(kakao_account.get("email"));

String nickname = properties.get("nickname").toString();
String email = kakao_account.get("email").toString();
String gender = kakao_account.get("gender").toString();
String age = kakao_account.get("age").toString();

userInfo.put("nickname", nickname);
userInfo.put("email", email);
userInfo.put("gender", gender);
userInfo.put("age", age);

return userInfo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.umc.DongnaeFriend.domain.user.service;

import com.umc.DongnaeFriend.domain.type.Age;
import com.umc.DongnaeFriend.domain.type.Gender;
import com.umc.DongnaeFriend.domain.type.YesNo;
import com.umc.DongnaeFriend.domain.user.dto.UserDto;
import com.umc.DongnaeFriend.domain.user.entity.User;
import com.umc.DongnaeFriend.domain.user.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Optional;

@Service
public class UserService {

@Autowired
UserRepository userRepository;

KakaoService kakaoService;

public void userValidation(HashMap<String, Object> userInfo) {
Optional<User> user= userRepository.findById((Long) userInfo.get("userId"));
if (user.isEmpty()) {
userRegister(userInfo);
}
}


//์œ ์ € ํšŒ์›๊ฐ€์ž…
public void userRegister(HashMap<String, Object> userInfo) {
//ํ•„์ˆ˜
String nickName = userInfo.get("nickname").toString();
//ํ•„์ˆ˜
String email = userInfo.get("email").toString();

Optional<String> gender = Optional.ofNullable(userInfo.get("gender").toString());
Optional<String> age = Optional.ofNullable(userInfo.get("age").toString());



userRepository.save(
User.builder()
.nickname(nickName)
.email(email)
//TODO : Gender ๊ฒฐ์ •
.gender(Gender.FEMALE)
//TODO : Age ๊ฒฐ์ •
.age(Age.AGE10)
.townCert(YesNo.NO)
.townCertCnt(0)
.infoCert(YesNo.NO)
.build()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.umc.DongnaeFriend.global.util;

import com.umc.DongnaeFriend.domain.user.repository.UserRepository;
import io.jsonwebtoken.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.Date;

import static com.umc.DongnaeFriend.config.JwtConfig.SECRET_KEY;

@Log4j2
@Component
public class JwtTokenProvider {

@Autowired
private UserRepository userRepository;

public JwtTokenProvider(UserRepository userRepository) {
this.userRepository = userRepository;
}

private final Long ACCESS_TOKEN_EXPIRE_LENGTH = 1000L * 60 * 60 * 24 * 14; //2WEEK
private final Long REFRESH_TOKEN_EXPIRE_LENGTH = 1000L * 60 * 60 * 24 * 30; //30DAY


//accessToken ์ƒ์„ฑ
public String createAccessToken(Long userId) {
Date now = new Date(); //ํ˜„์žฌ ์‹œ๊ฐ„
Date validity = new Date(now.getTime() + ACCESS_TOKEN_EXPIRE_LENGTH);


// CustomAuthentication user = (CustomAuthentication) authentication.getPrincipal();
//
// Claims claims = Jwts.claims().setSubject(user.getUsername());
// claims.put("userId", user.getId()); // ์‚ฌ์šฉ์ž ์•„์ด๋””
// claims.put("email", user.getEmail()); // ์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ

return Jwts.builder()
.signWith(SignatureAlgorithm.HS512, String.valueOf(SECRET_KEY))
.claim("userId", userId)
.setIssuedAt(now) //token ๋ฐœํ–‰ ์‹œ๊ฐ„
.setExpiration(validity)
.compact();
}





}
Loading

0 comments on commit 00a376f

Please sign in to comment.