Skip to content

Commit

Permalink
Merge pull request #8 from J2KB-3rd-Season/changmink
Browse files Browse the repository at this point in the history
토큰 기반 로그인 적용
  • Loading branch information
changmink authored Jun 10, 2021
2 parents 68ee2eb + 4f64c36 commit d5e280a
Show file tree
Hide file tree
Showing 17 changed files with 304 additions and 97 deletions.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
//querydsl 추가
implementation 'com.querydsl:querydsl-jpa'

// jjwt
compile 'io.jsonwebtoken:jjwt-api:0.11.2'
runtime 'io.jsonwebtoken:jjwt-impl:0.11.2',
'io.jsonwebtoken:jjwt-jackson:0.11.2'
}

test {
Expand Down
Empty file modified gradlew
100644 → 100755
Empty file.
26 changes: 26 additions & 0 deletions src/main/java/com/devin/dev/controller/Auth/AuthController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.devin.dev.controller.Auth;

import com.devin.dev.dto.user.UserLoginRequestDto;
import com.devin.dev.dto.user.UserSimpleDto;
import com.devin.dev.model.DefaultResponse;
import com.devin.dev.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class AuthController {
private final UserService userService;

@PostMapping("/user/login")
public DefaultResponse<?> login(@RequestBody UserLoginRequestDto userLoginRequestDto) {
return userService.login(userLoginRequestDto);
}

@PostMapping("/user/join")
public DefaultResponse<?> join(@RequestBody UserSimpleDto userSimpleDto) {
return userService.join(userSimpleDto);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.devin.dev.model.DefaultResponse;
import com.devin.dev.service.PostService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down
80 changes: 40 additions & 40 deletions src/main/java/com/devin/dev/controller/user/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,45 @@
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

@GetMapping("/login")
public String getLoginForm() {
return "loginPage";
}

@GetMapping("/signUp")
public String getSignUpForm() {
return "signupPage";
}

@PostMapping("/signUp")
public String signUp(@Valid UserSimpleDto form, BindingResult result) {

System.out.println("form = " + form);

if (result.hasErrors()) {
return "redirect:/";
}


userService.signUp(form);

return "redirect:/";
}

@GetMapping("/")
public String getIndex(Model model) {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username;
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
} else {
username = principal.toString();
}
model.addAttribute("username", username);

return "index";
}
// private final UserService userService;
//
// @GetMapping("/login")
// public String getLoginForm() {
// return "loginPage";
// }
//
// @GetMapping("/signUp")
// public String getSignUpForm() {
// return "signupPage";
// }
//
// @PostMapping("/signUp")
// public String signUp(@Valid UserSimpleDto form, BindingResult result) {
//
// System.out.println("form = " + form);
//
// if (result.hasErrors()) {
// return "redirect:/";
// }
//
//
// userService.signUp(form);
//
// return "redirect:/";
// }
//
// @GetMapping("/")
// public String getIndex(Model model) {
// Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
// String username;
// if (principal instanceof UserDetails) {
// username = ((UserDetails) principal).getUsername();
// } else {
// username = principal.toString();
// }
// model.addAttribute("username", username);
//
// return "index";
// }

}
9 changes: 9 additions & 0 deletions src/main/java/com/devin/dev/dto/user/UserLoginRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.devin.dev.dto.user;

import lombok.Data;

@Data
public class UserLoginRequestDto {
String userEmail;
String userPassword;
}
20 changes: 20 additions & 0 deletions src/main/java/com/devin/dev/dto/user/UserLoginResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.devin.dev.dto.user;

import com.devin.dev.entity.user.User;
import com.devin.dev.security.JwtAuthToken;
import lombok.Data;

@Data
public class UserLoginResponseDto {
private Long userId;
private String userProfile;
private String userName;
private String token;

public UserLoginResponseDto(User user, JwtAuthToken token) {
this.userId = user.getId();
this.userProfile = user.getProfile();
this.userName = user.getName();
this.token = token.getToken();
}
}
20 changes: 9 additions & 11 deletions src/main/java/com/devin/dev/dto/user/UserSimpleDto.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package com.devin.dev.dto.user;

import com.devin.dev.entity.user.UserStatus;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Data;

import javax.validation.constraints.NotEmpty;

@Data
public class UserSimpleDto {

private String name;
private String userName;
@NotEmpty(message = "email은 필수 입니다")
private String email;
private String userEmail;
@NotEmpty(message = "password는 필수 입니다")
private String password;
private String phone_number;
private String userPassword;
private String userPhoneNumber;

@QueryProjection
public UserSimpleDto(String name, String email, String password, String phone_number) {
this.name = name;
this.email = email;
this.password = password;
this.phone_number = phone_number;
public UserSimpleDto(String userName, String userEmail, String userPassword, String userPhoneNumber) {
this.userName = userName;
this.userEmail = userEmail;
this.userPassword = userPassword;
this.userPhoneNumber = userPhoneNumber;
}
}
10 changes: 4 additions & 6 deletions src/main/java/com/devin/dev/entity/user/User.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.devin.dev.entity.user;

import com.devin.dev.dto.user.UserDetailsDto;
import com.devin.dev.dto.user.UserSimpleDto;
import com.devin.dev.entity.base.Created;
import com.devin.dev.entity.post.Post;
import com.devin.dev.entity.post.PostTag;
import com.devin.dev.entity.reply.Reply;
import com.devin.dev.entity.service.CustomerService;
import lombok.AccessLevel;
Expand Down Expand Up @@ -78,10 +76,10 @@ public User(String name, String email, String password, String phone_number, Use
}

public User(UserSimpleDto userDto) {
this.name = userDto.getName();
this.email = userDto.getEmail();
this.password = userDto.getPassword();
this.phone_number = userDto.getPhone_number();
this.name = userDto.getUserName();
this.email = userDto.getUserEmail();
this.password = userDto.getUserPassword();
this.phone_number = userDto.getUserPhoneNumber();
this.status = UserStatus.ACTIVE;
this.exp = 0L;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/devin/dev/security/JwtAuthToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.devin.dev.security;

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class JwtAuthToken {
private String token;
}
66 changes: 66 additions & 0 deletions src/main/java/com/devin/dev/security/JwtAuthTokenProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.devin.dev.security;

import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;

@Component
public class JwtAuthTokenProvider {
private static final String SECRET_KEY = "J2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KBJ2KB";
private static final long EXPIRATION_MS = 1000 * 60 * 60 * 24;

public JwtAuthToken publishToken(Long userId) {
return JwtAuthToken.builder().token(generateToken(userId)).build();
}

private String generateToken(Long userId) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime expiredAt = now.plus(EXPIRATION_MS, ChronoUnit.MILLIS);
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET_KEY));
return Jwts.builder()
.setSubject(String.valueOf(userId))
.setIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()))
.setExpiration(Date.from(expiredAt.atZone(ZoneId.systemDefault()).toInstant()))
.signWith(key)
.compact();
}

public String parseToken(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}

public Long getUserId(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}

public boolean validateToken(String token) {
if (token != null && !token.equals("")) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
throw new RuntimeException();
}
}
return false;
}


}
4 changes: 0 additions & 4 deletions src/main/java/com/devin/dev/security/LoginSuccessHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,5 @@ public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
HttpSession session = request.getSession();

session.setAttribute("greeting", "welcome " + authentication.getName());
System.out.println("session.getAttribute(\"greeting\") = " + session.getAttribute("greeting"));
response.sendRedirect("/");
}
}
36 changes: 16 additions & 20 deletions src/main/java/com/devin/dev/security/SecurityConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String[] PUBLIC_URI = {
"/user/**", "/postlist/**"
};

@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
Expand All @@ -20,28 +25,19 @@ public PasswordEncoder getPasswordEncoder() {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().disable() // cors 비활성화
.csrf().disable() // csrf 비활성화
.authorizeRequests()
.antMatchers("/login", "/signUp")
.cors().disable() // cors 비활성화
.csrf().disable() // csrf 비활성화
.authorizeRequests()
.antMatchers("/user/**", "/postlist/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/signIn")
.usernameParameter("email")
.passwordParameter("password")
.successHandler(new LoginSuccessHandler())
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login");
.anyRequest()
.authenticated();

http.addFilterBefore(tokenAuthFilter(), UsernamePasswordAuthenticationFilter.class);
}

@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/postlist/**");
@Bean
public TokenAuthFilter tokenAuthFilter() {
return new TokenAuthFilter();
}
}
Loading

0 comments on commit d5e280a

Please sign in to comment.