Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,25 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'

// TODO: login
// implementation 'org.springframework.boot:spring-boot-starter-security'
// implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

implementation 'org.json:json:20230227'

implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'


implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-java:8.0.31'
implementation 'org.springframework.boot:spring-boot-starter-security'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

// TODO: login
// testImplementation 'org.springframework.security:spring-security-test'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.itsu.threedays.domain.user.controller;

import com.itsu.threedays.config.jwt.JwtTokenProvider;
import com.itsu.threedays.domain.user.dto.UserDto;
import com.itsu.threedays.domain.user.entity.UserEntity;
import com.itsu.threedays.domain.user.entity.role.Role;
import com.itsu.threedays.domain.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.http.*;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;

@RestController
@RequiredArgsConstructor
@RequestMapping("api")
@Slf4j
@Controller
public class KaKaoLoginController {

private final UserService userService;
private final JwtTokenProvider tokenProvider;

@PostMapping("/login")
ResponseEntity<String> responseJwtToken(@RequestBody UserDto userDto) { //파베 토큰, 엑세스 토큰, 디바이스 아디 받아옴
String KAKAO_USERINFO_REQUEST_URL = "https://kapi.kakao.com/v2/user/me";

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "Bearer " + userDto.getKakaoAccessToken());
//Bearer 이후 한칸 띄기(kakao) + accesstoken 헤더에 넣어야함

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(httpHeaders);

RestTemplate restTemplate = new RestTemplate(); //서버에서 다른서버로 연결할 때 쓰는 RestTemplate
try {
ResponseEntity<String> response = restTemplate.exchange(KAKAO_USERINFO_REQUEST_URL, HttpMethod.GET, request, String.class);
//카카오에서 받은 거를 response로 담김
log.info("response : {}", response);
log.info("response.getBody() : {}", response.getBody());

JSONObject jsonObject = new JSONObject(response.getBody());
JSONObject kakao_account = jsonObject.getJSONObject("kakao_account");//kakao-account : 키값

String email = kakao_account.getString("email");
log.info("email : {}", email);
String nickname = kakao_account.getJSONObject("profile").getString("nickname");
log.info("nickname : {}", nickname);

//security config - password는 암호화해서 저장

SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(Role.USER.toString());
//if (userService.findByEmail(email).toString().isEmpty()) {
if (!userService.isUserExist(email)){
log.info("회원가입 시작");
UserEntity user = UserEntity.builder()
.role(Role.USER)
.id(userDto.getId())
.email(email)
.nickname(nickname)
.password(new BCryptPasswordEncoder().encode(email))
// .fireBaseToken(userDto.getFirebaseToken())
.build();
userService.saveUser(user);
log.info("user: {}",user);

User createUser = new User(email, "", Collections.singleton(simpleGrantedAuthority));
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(createUser, userDto.getKakaoAccessToken(), Collections.singleton(simpleGrantedAuthority));
String token = tokenProvider.createToken(usernamePasswordAuthenticationToken);
log.info("token 발급: {}", token);
return new ResponseEntity<>(token, HttpStatus.OK);

}
// else {
// log.info("이미 등록된 회원");
// if (!userService.) { //파이어베이스 토큰 다르면 업데이트
// log.info("firebaseToken Update");
// User userId = userService.getUserId(email).get();
//// userId.setFireBaseToken(userDto.getFirebaseToken());
// userService.saveUser(userId);
// }
//
// User updateUser = new User(email, "", Collections.singleton(simpleGrantedAuthority));
// UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(updateUser, userDto.getKakaoAccessToken(), Collections.singleton(simpleGrantedAuthority));
// String token = tokenProvider.createToken(usernamePasswordAuthenticationToken);
// log.info("token 발급: {}", token);
// return new ResponseEntity<>(token, HttpStatus.OK);
// }
} catch (HttpClientErrorException e) {
log.error("access token err : {}", e.getMessage());
} catch (Exception e) {
throw new RuntimeException(e);
}
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

@GetMapping("/test")
public ResponseEntity<String> testApi(HttpServletRequest request) {
String jwt = tokenProvider.resolveToken(request);
log.info("testApi - jwt: {}",jwt);
if (jwt == null) {
return new ResponseEntity<>("JWT not found!", HttpStatus.BAD_REQUEST);
}

if (tokenProvider.validateToken(jwt)) {
return new ResponseEntity<>("JWT is valid", HttpStatus.OK);
} else {
return new ResponseEntity<>("JWT is invalid", HttpStatus.UNAUTHORIZED);
}
}

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

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
Long id;
String nickname;
String email;
String kakaoAccessToken;
//String firebaseToken;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.itsu.threedays.domain.user.entity;

import com.itsu.threedays.domain.user.entity.role.Role;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@AllArgsConstructor
@NoArgsConstructor
@Entity
@Builder
@Data
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;

@Column(name = "NICKNAME")
private String nickname;

@Column(name = "EMAIL")
private String email;

@Column(name = "PASSWORD")
private String password;

@Enumerated(EnumType.STRING)
private Role role;

// @Enumerated(EnumType.STRING)
// private OauthProvider oauthProvider;

}
14 changes: 14 additions & 0 deletions src/main/java/com/itsu/threedays/domain/user/entity/role/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.itsu.threedays.domain.user.entity.role;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum Role {
USER("ROLE_USER"),
ADMIN("ROLE_ADMIN"),
SOCIAL("ROLE_SOCIAL");
private final String value;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.itsu.threedays.domain.user.repository;

import com.itsu.threedays.domain.user.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<UserEntity,Long> {
Optional<UserEntity> findByEmail(String email);
//Optional<UserEntity> findById(String E)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.itsu.threedays.domain.user.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
@Slf4j
public class KakaoUserService {


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.itsu.threedays.domain.user.service;


import com.itsu.threedays.domain.user.entity.UserEntity;
import com.itsu.threedays.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Optional;


@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;

public UserEntity findByEmail(String email) {
Optional<UserEntity> byEmail = userRepository.findByEmail(email);
return byEmail.get();
}
public boolean isUserExist(String email){
try {
findByEmail(email);
return true;
} catch (Exception e) {
return false;
}
}

public void saveUser(UserEntity user){
userRepository.save(user);
}

// public Optional getUserId(String email){
// userRepository.
// }





}
4 changes: 3 additions & 1 deletion src/main/resources/application-local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ spring:
datasource:
url: jdbc:mysql://localhost:3306/threedays
username: root
password:
password: 112900
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
Expand All @@ -13,3 +13,5 @@ spring:
properties:
hibernate:
format_sql: true
jwt:
secret: threedaysapitokensecretkey123149398230