Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 6차 데모데이 배포를 진행한다. #860

Merged
merged 47 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3dcd280
[BE] 로그아웃이 안되는 오류를 해결한다. (#703)
tkdgur0906 Sep 27, 2024
18875ea
[BE] 커스텀 체크리스트 질문 조회 관련 api 구현 방식을 일치시킨다. (#723)
tkdgur0906 Oct 3, 2024
6cf0e78
[BE] Redierect URI를 여러 개 받을 수 있도록 카카오 로그인 구현 방식을 변경한다. (#725)
JINU-CHANG Oct 4, 2024
b10cd08
[BE] DEV와 DEV-BE 브랜치를 병합한다. (#738)
JINU-CHANG Oct 4, 2024
e944dfd
fix: Redirect Uri 값 저장하는 과정에서 발생하는 에러 해결 (#741)
JINU-CHANG Oct 4, 2024
fcc8993
[BE] DEV와 DEV-BE 브랜치를 병합한다. (#742)
JINU-CHANG Oct 4, 2024
1cc124b
[BE] Location URI를 프론트 기준으로 변경한다. (#744)
JINU-CHANG Oct 4, 2024
37be1ad
[BE] DEV와 DEV-BE를 병합한다. (#745)
JINU-CHANG Oct 4, 2024
f237d3b
[BE] User에 로그인 타입을 추가한다. (#736)
tkdgur0906 Oct 5, 2024
5f05664
[BE] Lombok을 적용한다. (#731)
JINU-CHANG Oct 6, 2024
1cfd187
[BE] CORS 설정에 exposedHeader를 추가한다. (#751)
JINU-CHANG Oct 6, 2024
fff6bb7
[BE] DEV와 DEV-BE를 병합한다. (#752)
JINU-CHANG Oct 6, 2024
38f99e3
[BE] 체크리스트에 지하철을 2개 이상 저장할 수 있게 한다.(작성/조회) (#753)
tsulocalize Oct 7, 2024
562f36d
[BE] 토큰 관련 코드를 리팩토링한다. (#754)
JINU-CHANG Oct 7, 2024
398a3e8
[BE] 토큰 확인하는 API를 구현한다. (#767)
JINU-CHANG Oct 10, 2024
b875ac7
DEV-BE 코드를 DEV와 병합한다 (#779)
tsulocalize Oct 10, 2024
7622574
[BE] 테이블 drop 순서 오류 수정 (#780)
tsulocalize Oct 10, 2024
02eaad0
dev-be를 dev에 병합한다 (#781)
tsulocalize Oct 10, 2024
351a7d9
[BE] 회원가입 기능을 구현한다. (#774)
tkdgur0906 Oct 11, 2024
8d8472d
[BE] 로케이션 헤더를 수정한다 (#795)
tsulocalize Oct 14, 2024
59eb9ac
[BE] 일반 로그인을 구현한다. (#775)
shin-jisong Oct 15, 2024
c1c5a6c
[BE] 토큰 무효화 api를 구현한다. (#787)
tkdgur0906 Oct 15, 2024
9c58452
[BE] 액세스 토큰 존재 여부를 반환한다. (#800)
JINU-CHANG Oct 15, 2024
45e1ee6
[BE] DEV와 DEV-BE를 머지한다. (#806)
JINU-CHANG Oct 15, 2024
3860cc7
[BE] 방끗 자체 에러코드를 구현한다. (#789)
shin-jisong Oct 15, 2024
3809515
[BE] 로그아웃 path를 변경한다. (#801)
shin-jisong Oct 15, 2024
c970a48
[BE] 좋아요 중복 요청 시 정상 상태코드 반환 및 중복 저장을 방지한다. (#739)
tkdgur0906 Oct 16, 2024
69f2c12
[BE] 회원 탈퇴를 구현한다. (#808)
shin-jisong Oct 16, 2024
ea63ea3
[BE] Enum 데이터를 DB로 옮긴다. (#810)
JINU-CHANG Oct 17, 2024
46dafd4
docs: update backend-dev-cd.yml
shin-jisong Oct 17, 2024
b8c6540
[BE] 파라미터 오류 시 에러 메시지를 정상적으로 수정한다 (#819)
tsulocalize Oct 17, 2024
c6e38fc
[BE] dev-be 코드를 dev에 병합한다 (#820)
tsulocalize Oct 17, 2024
6cce5e7
docs: update backend-dev-cd.yml
shin-jisong Oct 17, 2024
75ea501
[BE] sql 오류를 수정한다. (#822)
tsulocalize Oct 17, 2024
fe1409c
[BE] dev-be 코드 내용을 dev에 반영한다 (#823)
tsulocalize Oct 17, 2024
f3d540c
docs: update backend-dev-cd.yml
shin-jisong Oct 17, 2024
865192f
[BE] dev-be 코드 내용을 dev에 재반영한다 (#824)
tsulocalize Oct 17, 2024
fa6c1fa
[BE] cicd 파일을 수정한다. (#825)
tkdgur0906 Oct 17, 2024
4733dd7
[BE] sql 오류를 수정한다 (#826)
tsulocalize Oct 17, 2024
74052e3
Merge branch 'dev' into dev-be
tsulocalize Oct 17, 2024
2a709c8
[BE] dev-be 코드를 dev에 반영한다 (#827)
tsulocalize Oct 17, 2024
3e9a258
[BE] 없어진 아티클을 복구한다. (#832)
tsulocalize Oct 18, 2024
6bc9839
[BE] dev-be를 dev로 병합한다. (#835)
tkdgur0906 Oct 18, 2024
a222313
[BE] 질문이 없는 카테고리는 보내지 않도록 수정한다. (#842)
JINU-CHANG Oct 21, 2024
5f362a3
[BE] dev-be를 dev로 병합한다. (#846)
tkdgur0906 Oct 21, 2024
662888a
[BE] 스키마 변경에 따른 무중단 배포를 진행한다. (#858)
JINU-CHANG Oct 22, 2024
d88f3ed
[BE] DEV와 DEV-BE를 병합한다. (#859)
JINU-CHANG Oct 22, 2024
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
12 changes: 11 additions & 1 deletion .github/workflows/backend-dev-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,18 @@ jobs:
with:
name: bang-ggood-be-develop-jar

- name: Create unhealth_flag file
run: echo "unhealth" | sudo tee /etc/nginx/sites-available/unhealth_flag.txt > /dev/null


- name: Sleep for 30 seconds
run: sleep 30

- name: Turn off the server 8080 if runs
run: sudo fuser -k -n tcp 8080 || true

- name: Start server
run: sudo nohup java -jar -Dspring.profiles.active=dev -Duser.timezone=Asia/Seoul ./backend/bang-ggood/build/libs/*SNAPSHOT.jar > /home/ubuntu/actions-runner/server.log 2>&1 &

- name: Delete unhealth_flag file
run: sudo rm /etc/nginx/sites-available/unhealth_flag.txt
Binary file added backend/bang-ggood/.DS_Store
Binary file not shown.
8 changes: 6 additions & 2 deletions backend/bang-ggood/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.projectlombok:lombok'
implementation 'com.mysql:mysql-connector-j'
implementation 'com.opencsv:opencsv:5.9'

implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
implementation 'io.jsonwebtoken:jjwt-gson:0.11.2'
implementation 'com.mysql:mysql-connector-j'
implementation 'com.opencsv:opencsv:5.9'

annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
Binary file added backend/bang-ggood/src/.DS_Store
Binary file not shown.
Binary file added backend/bang-ggood/src/main/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ArticleController(ArticleService articleService) {
public ResponseEntity<Void> createArticle(@AuthRequiredPrincipal User user,
@Valid @RequestBody ArticleCreateRequest request) {
Long id = articleService.createArticle(request);
return ResponseEntity.created(URI.create("articles/" + id)).build();
return ResponseEntity.created(URI.create("/article/" + id)).build();
}

@GetMapping("/articles/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.Objects;

import static lombok.AccessLevel.PROTECTED;

@Getter
@NoArgsConstructor(access = PROTECTED)
@Entity
public class Article extends BaseEntity {

Expand All @@ -32,33 +38,6 @@ public Article(String title, String content, String keyword, String summary, Str
this.thumbnail = thumbnail;
}

protected Article() {
}

public Long getId() {
return id;
}

public String getTitle() {
return title;
}

public String getContent() {
return content;
}

public String getKeyword() {
return keyword;
}

public String getSummary() {
return summary;
}

public String getThumbnail() {
return thumbnail;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ default Article getById(Long id) {

@Query("SELECT a FROM Article a " +
"WHERE a.deleted = false " +
"ORDER BY a.createdAt DESC ")
"ORDER BY a.createdAt DESC, a.id DESC")
List<Article> findLatestArticles();

@Modifying(flushAutomatically = true, clearAutomatically = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@

import com.bang_ggood.article.domain.Article;
import com.bang_ggood.article.dto.request.ArticleCreateRequest;
import com.bang_ggood.article.dto.response.ArticlesResponse;
import com.bang_ggood.article.dto.response.ArticleResponse;
import com.bang_ggood.article.dto.response.ArticlesResponse;
import com.bang_ggood.article.dto.response.ArticlesResponses;
import com.bang_ggood.article.repository.ArticleRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@RequiredArgsConstructor
@Service
public class ArticleService {

private final ArticleRepository articleRepository;

public ArticleService(ArticleRepository articleRepository) {
this.articleRepository = articleRepository;
}

@Transactional
public long createArticle(ArticleCreateRequest request) {
Article article = request.toEntity();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.bang_ggood.auth.config;

import com.bang_ggood.auth.controller.CookieResolver;
import com.bang_ggood.auth.controller.cookie.CookieResolver;
import com.bang_ggood.auth.service.AuthService;
import com.bang_ggood.global.exception.BangggoodException;
import com.bang_ggood.global.exception.ExceptionCode;
import com.bang_ggood.user.domain.User;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
Expand Down Expand Up @@ -35,12 +33,8 @@ public User resolveArgument(MethodParameter parameter, ModelAndViewContainer mav
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();

// TODO 리팩토링
if (request.getCookies() == null || cookieResolver.isTokenNotExist(request.getCookies())) {
throw new BangggoodException(ExceptionCode.AUTHENTICATION_TOKEN_EMPTY);
}

String token = cookieResolver.extractAccessToken(request.getCookies());
cookieResolver.checkLoginRequired(request);
String token = cookieResolver.extractAccessToken(request);
return authService.getAuthUser(token);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.bang_ggood.auth.config;

import com.bang_ggood.auth.controller.CookieResolver;
import com.bang_ggood.auth.controller.cookie.CookieResolver;
import com.bang_ggood.auth.service.AuthService;
import com.bang_ggood.user.domain.User;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -33,11 +33,11 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();

if (request.getCookies() == null || cookieResolver.isTokenNotExist(request.getCookies())) {
if (cookieResolver.isTokenEmpty(request)) {
return authService.assignGuestUser();
}

String token = cookieResolver.extractAccessToken(request.getCookies());
String token = cookieResolver.extractAccessToken(request);
return authService.getAuthUser(token);
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,51 @@
package com.bang_ggood.auth.controller;

import com.bang_ggood.auth.config.AuthRequiredPrincipal;
import com.bang_ggood.auth.controller.cookie.CookieProvider;
import com.bang_ggood.auth.controller.cookie.CookieResolver;
import com.bang_ggood.auth.dto.request.LocalLoginRequestV1;
import com.bang_ggood.auth.dto.request.OauthLoginRequest;
import com.bang_ggood.auth.dto.request.RegisterRequestV1;
import com.bang_ggood.auth.dto.response.AuthTokenResponse;
import com.bang_ggood.auth.dto.response.TokenExistResponse;
import com.bang_ggood.auth.service.AuthService;
import com.bang_ggood.user.domain.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import java.net.URI;

@RequiredArgsConstructor
@RestController
public class AuthController {

private final AuthService authService;
private final CookieProvider cookieProvider;
private final CookieResolver cookieResolver;

public AuthController(AuthService authService, CookieProvider cookieProvider, CookieResolver cookieResolver) {
this.authService = authService;
this.cookieProvider = cookieProvider;
this.cookieResolver = cookieResolver;
@PostMapping("/v1/local-auth/register")
public ResponseEntity<Void> register(@Valid @RequestBody RegisterRequestV1 request) {
Long userId = authService.register(request);
return ResponseEntity.created(URI.create("/v1/local-auth/register/" + userId)).build();
}

@DeleteMapping("/v1/withdraw")
public ResponseEntity<Void> withdraw(@AuthRequiredPrincipal User user) {
authService.withdraw(user);
return ResponseEntity.noContent().build();
}

@PostMapping("/oauth/login")
public ResponseEntity<Void> login(@Valid @RequestBody OauthLoginRequest request) {
AuthTokenResponse response = authService.login(request);
public ResponseEntity<Void> oauthLogin(@Valid @RequestBody OauthLoginRequest request) {
AuthTokenResponse response = authService.oauthLogin(request);

ResponseCookie accessTokenCookie = cookieProvider.createAccessTokenCookie(response.accessToken());
ResponseCookie refreshTokenCookie = cookieProvider.createRefreshTokenCookie(response.refreshToken());
Expand All @@ -41,14 +56,29 @@ public ResponseEntity<Void> login(@Valid @RequestBody OauthLoginRequest request)
.build();
}

@PostMapping("/oauth/logout")
@PostMapping("/v1/local-auth/login")
public ResponseEntity<Void> localLogin(@Valid @RequestBody LocalLoginRequestV1 request) {
AuthTokenResponse response = authService.localLogin(request);

ResponseCookie accessTokenCookie = cookieProvider.createAccessTokenCookie(response.accessToken());
ResponseCookie refreshTokenCookie = cookieProvider.createRefreshTokenCookie(response.refreshToken());

return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, accessTokenCookie.toString())
.header(HttpHeaders.SET_COOKIE, refreshTokenCookie.toString())
.build();
}

@PostMapping("/v1/logout")
public ResponseEntity<Void> logout(@AuthRequiredPrincipal User user,
HttpServletRequest httpServletRequest) {
String accessToken = cookieResolver.extractAccessToken(httpServletRequest.getCookies());
String refreshToken = cookieResolver.extractRefreshToken(httpServletRequest.getCookies());
String accessToken = cookieResolver.extractAccessToken(httpServletRequest);
String refreshToken = cookieResolver.extractRefreshToken(httpServletRequest);

authService.logout(accessToken, refreshToken, user);
ResponseCookie deletedAccessTokenCookie = cookieProvider.deleteAccessTokenCookie(accessToken);
ResponseCookie deletedRefreshTokenCookie = cookieProvider.deleteRefreshTokenCookie(refreshToken);

ResponseCookie deletedAccessTokenCookie = cookieProvider.deleteAccessTokenCookie();
ResponseCookie deletedRefreshTokenCookie = cookieProvider.deleteRefreshTokenCookie();

return ResponseEntity.noContent()
.header(HttpHeaders.SET_COOKIE, deletedAccessTokenCookie.toString())
Expand All @@ -57,13 +87,35 @@ public ResponseEntity<Void> logout(@AuthRequiredPrincipal User user,
}

@PostMapping("/accessToken/reissue")
public ResponseEntity<Void> reIssueAccessToken(HttpServletRequest httpServletRequest) {
String refreshToken = cookieResolver.extractRefreshToken(httpServletRequest.getCookies());
String accessToken = authService.reIssueAccessToken(refreshToken);
public ResponseEntity<Void> reissueAccessToken(HttpServletRequest httpServletRequest) {
cookieResolver.checkLoginRequired(httpServletRequest);

String refreshToken = cookieResolver.extractRefreshToken(httpServletRequest);
String accessToken = authService.reissueAccessToken(refreshToken);

ResponseCookie accessTokenCookie = cookieProvider.createAccessTokenCookie(accessToken);
return ResponseEntity.ok()
.header(HttpHeaders.SET_COOKIE, accessTokenCookie.toString())
.build();
}

@GetMapping("/token-exist")
public ResponseEntity<TokenExistResponse> check(HttpServletRequest httpServletRequest) {
boolean isAccessTokenExist = !cookieResolver.isAccessTokenEmpty(httpServletRequest);
boolean isRefreshTokenExist = !cookieResolver.isRefreshTokenEmpty(httpServletRequest);

TokenExistResponse tokenExistResponse = TokenExistResponse.from(isAccessTokenExist, isRefreshTokenExist);
return ResponseEntity.ok(tokenExistResponse);
}

@DeleteMapping("/token")
public ResponseEntity<Void> deleteToken() {
ResponseCookie deletedAccessTokenCookie = cookieProvider.deleteAccessTokenCookie();
ResponseCookie deletedRefreshTokenCookie = cookieProvider.deleteRefreshTokenCookie();

return ResponseEntity.noContent()
.header(HttpHeaders.SET_COOKIE, deletedAccessTokenCookie.toString())
.header(HttpHeaders.SET_COOKIE, deletedRefreshTokenCookie.toString())
.build();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.bang_ggood.auth.controller;
package com.bang_ggood.auth.controller.cookie;

import com.bang_ggood.auth.service.JwtTokenProperties;
import com.bang_ggood.auth.service.jwt.JwtTokenProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseCookie;
import org.springframework.stereotype.Component;
Expand All @@ -9,8 +9,9 @@
@Component
public class CookieProvider {

public static final String ACCESS_TOKEN_COOKIE_NAME = "accessToken";
public static final String REFRESH_TOKEN_COOKIE_NAME = "refreshToken";
protected static final String ACCESS_TOKEN_COOKIE_NAME = "accessToken";
protected static final String REFRESH_TOKEN_COOKIE_NAME = "refreshToken";

private final JwtTokenProperties jwtTokenProperties;
private final String domain;

Expand Down Expand Up @@ -46,11 +47,11 @@ private ResponseCookie createCookie(String tokenName, String token, long expired
.build();
}

public ResponseCookie deleteAccessTokenCookie(String token) {
public ResponseCookie deleteAccessTokenCookie() {
return deleteCookie(ACCESS_TOKEN_COOKIE_NAME);
}

public ResponseCookie deleteRefreshTokenCookie(String token) {
public ResponseCookie deleteRefreshTokenCookie() {
return deleteCookie(REFRESH_TOKEN_COOKIE_NAME);
}

Expand Down
Loading
Loading