This repository has been archived by the owner on Oct 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#171] feat: auth 관련 controller 를 구현한다.
- Loading branch information
1 parent
3369bfc
commit ba7fb7b
Showing
6 changed files
with
179 additions
and
0 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
43 changes: 43 additions & 0 deletions
43
...ary-core-api/src/main/java/com/woowacourse/tecobrary/web/oauth/GithubOAuthController.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,43 @@ | ||
package com.woowacourse.tecobrary.web.oauth; | ||
|
||
import com.woowacourse.tecobrary.common.dto.CoreApiResponse; | ||
import com.woowacourse.tecobrary.web.github.api.GithubApiService; | ||
import com.woowacourse.tecobrary.web.github.dto.GithubApiResponseDto; | ||
import com.woowacourse.tecobrary.web.github.dto.UserJwtInfoDto; | ||
import com.woowacourse.tecobrary.web.github.utils.GithubUserApiUrlBuilder; | ||
import com.woowacourse.tecobrary.web.oauth.jwt.JwtGenerator; | ||
import com.woowacourse.tecobrary.web.oauth.service.GithubUserService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.CrossOrigin; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.servlet.view.RedirectView; | ||
|
||
@Controller | ||
@Slf4j | ||
@CrossOrigin(origins = "*") | ||
@RequiredArgsConstructor | ||
public class GithubOAuthController { | ||
|
||
private final GithubUserApiUrlBuilder githubUserApiUrlBuilder; | ||
private final GithubApiService githubApiService; | ||
private final GithubUserService githubUserService; | ||
private final JwtGenerator jwtGenerator; | ||
|
||
@GetMapping("/login/github/oauth2") | ||
public RedirectView github() { | ||
return new RedirectView(githubUserApiUrlBuilder.oauth()); | ||
} | ||
|
||
@GetMapping("/login/tecobrary") | ||
public CoreApiResponse<GithubApiResponseDto> userAuth(@RequestParam String code) { | ||
String accessToken = githubApiService.getGithubAccessToken(code); | ||
UserJwtInfoDto userJwtInfoDto = githubUserService.getUserByGithubInfo(accessToken); | ||
return CoreApiResponse.success(GithubApiResponseDto.builder() | ||
.user(userJwtInfoDto) | ||
.token(jwtGenerator.generateToken(userJwtInfoDto)) | ||
.build()); | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
tecobrary-core-api/src/main/java/com/woowacourse/tecobrary/web/oauth/jwt/JwtGenerator.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,84 @@ | ||
package com.woowacourse.tecobrary.web.oauth.jwt; | ||
|
||
import com.woowacourse.tecobrary.web.github.dto.UserJwtInfoDto; | ||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.ExpiredJwtException; | ||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.SignatureAlgorithm; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Date; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
|
||
@Component | ||
public class JwtGenerator { | ||
|
||
private static final long JWT_TOKEN_VALIDITY = 60 * 60 * 24 * 7; // one week | ||
|
||
private final String secret; | ||
|
||
public JwtGenerator(@Value("jwt.secret") String secret) { | ||
this.secret = secret; | ||
} | ||
|
||
public String generateToken(UserJwtInfoDto userJwtInfoVo) { | ||
Map<String, Object> claims = new LinkedHashMap<>(); | ||
claims.put("id", userJwtInfoVo.getId()); | ||
claims.put("email", userJwtInfoVo.getEmail()); | ||
claims.put("name", userJwtInfoVo.getName()); | ||
claims.put("authorization", userJwtInfoVo.getAuthorization()); | ||
claims.put("avatarUrl", userJwtInfoVo.getAvatarUrl()); | ||
|
||
Map<String, Object> headers = new LinkedHashMap<>(); | ||
headers.put("alg", "HS256"); | ||
headers.put("typ", "JWT"); | ||
return doGenerateToken(claims, headers); | ||
} | ||
|
||
public Boolean validateToken(String token, UserJwtInfoDto userJwtInfoVo) { | ||
String userNo = getUserIdFromToken(token); | ||
return (userNo.equals(userJwtInfoVo.getId()) && !isTokenExpired(token)); | ||
} | ||
|
||
public Boolean isTokenExpired(String token) { | ||
try { | ||
Date expiration = getExpirationDateFromToken(token); | ||
return expiration.before(new Date()); | ||
} catch (ExpiredJwtException e) { | ||
return true; | ||
} | ||
} | ||
|
||
public String getUserIdFromToken(String token) { | ||
return (String) getClaimFromToken(token, claims -> claims.get("id")); | ||
} | ||
|
||
private String doGenerateToken(Map<String, Object> claims, Map<String, Object> headers) { | ||
return Jwts.builder() | ||
.signWith(SignatureAlgorithm.HS256, secret) | ||
.setHeader(headers) | ||
.setClaims(claims) | ||
.setIssuedAt(new Date(System.currentTimeMillis())) | ||
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000)) | ||
.compact(); | ||
} | ||
|
||
private Date getExpirationDateFromToken(String token) { | ||
return getClaimFromToken(token, Claims::getExpiration); | ||
} | ||
|
||
private <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) { | ||
Claims claims = getAllClaimsFromToken(token); | ||
return claimsResolver.apply(claims); | ||
} | ||
|
||
private Claims getAllClaimsFromToken(String token) { | ||
return Jwts.parser() | ||
.setSigningKey(secret) | ||
.parseClaimsJws(token) | ||
.getBody(); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
...core-api/src/main/java/com/woowacourse/tecobrary/web/oauth/service/GithubUserService.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,44 @@ | ||
package com.woowacourse.tecobrary.web.oauth.service; | ||
|
||
import com.woowacourse.tecobrary.domain.user.entity.User; | ||
import com.woowacourse.tecobrary.domain.user.repository.UserRepository; | ||
import com.woowacourse.tecobrary.web.github.api.GithubApiService; | ||
import com.woowacourse.tecobrary.web.github.dto.GithubUserInfoDto; | ||
import com.woowacourse.tecobrary.web.github.dto.UserJwtInfoDto; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class GithubUserService { | ||
|
||
private final UserRepository userRepository; | ||
private final GithubApiService githubApiService; | ||
|
||
public UserJwtInfoDto getUserByGithubInfo(String githubAccessToken) { | ||
GithubUserInfoDto githubUserInfoDto = githubApiService.getGithubUserInfo(githubAccessToken); | ||
|
||
User user = userRepository.findByGithubId(githubUserInfoDto.getId()) | ||
.orElse(newGithubUser(githubAccessToken, githubUserInfoDto)); | ||
|
||
return UserJwtInfoDto.builder() | ||
.id(user.getId()) | ||
.name(user.getName()) | ||
.email(user.getEmail()) | ||
.avatarUrl(user.getAvatarUrl()) | ||
.authorization(user.getAuthorization()) | ||
.build(); | ||
} | ||
|
||
private User newGithubUser(String githubAccessToken, GithubUserInfoDto githubUser) { | ||
String email = githubApiService.getGithubUserEmail(githubAccessToken); | ||
User user = User.builder() | ||
.githubId(githubUser.getId()) | ||
.email(email) | ||
.avatarUrl(githubUser.getAvatar_url()) | ||
.name(githubUser.getName()) | ||
.authorization("NONE") | ||
.build(); | ||
return userRepository.save(user); | ||
} | ||
} |
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
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