Skip to content

Commit 5dfaed2

Browse files
committedOct 14, 2021
create: naver smsService
1 parent 90564d2 commit 5dfaed2

15 files changed

+246
-47
lines changed
 

‎build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ dependencies {
2626
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
2727
implementation 'io.jsonwebtoken:jjwt:0.9.1' //json web token
2828
compileOnly 'org.projectlombok:lombok'
29+
compileOnly 'org.apache.httpcomponents:httpcore:4.4.1'
30+
compileOnly 'org.apache.httpcomponents:httpclient:4.5'
2931
runtimeOnly 'mysql:mysql-connector-java'
3032
annotationProcessor 'org.projectlombok:lombok'
3133
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package team.streetalk.controller;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.http.HttpStatus;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestBody;
8+
import org.springframework.web.bind.annotation.RestController;
9+
import team.streetalk.dto.LoginRequest;
10+
import team.streetalk.dto.LoginResponse;
11+
import team.streetalk.dto.MessageWithData;
12+
import team.streetalk.service.UserService;
13+
14+
15+
@RestController
16+
@RequiredArgsConstructor
17+
public class AdminController {
18+
private final UserService userService;
19+
20+
21+
22+
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,48 @@
11
package team.streetalk.controller;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
34
import lombok.RequiredArgsConstructor;
45
import org.springframework.http.HttpStatus;
56
import org.springframework.http.ResponseEntity;
67
import org.springframework.web.bind.annotation.*;
78
import team.streetalk.dto.LoginRequest;
89
import team.streetalk.dto.LoginResponse;
10+
import team.streetalk.dto.MessageOnly;
911
import team.streetalk.dto.MessageWithData;
12+
import team.streetalk.dto.sms.SmsResponse;
13+
import team.streetalk.service.SmsService;
1014
import team.streetalk.service.UserService;
1115

16+
import javax.servlet.http.HttpServletRequest;
17+
import java.io.UnsupportedEncodingException;
18+
import java.net.URISyntaxException;
19+
import java.security.InvalidKeyException;
20+
import java.security.NoSuchAlgorithmException;
21+
1222

1323
@RestController
1424
@RequiredArgsConstructor
1525
public class UserController {
1626
private final UserService userService;
27+
private final SmsService smsService;
1728

1829
@PostMapping("/users/login")
1930
public ResponseEntity<MessageWithData> signIn(@RequestBody LoginRequest loginRequest) {
2031
LoginResponse data = userService.login(loginRequest);
2132
return new ResponseEntity<>(new MessageWithData(200, true, "Gave you home", data), HttpStatus.OK);
2233
}
2334

35+
@PostMapping("/user/test")
36+
public ResponseEntity<MessageWithData> test(HttpServletRequest req) throws UnsupportedEncodingException, NoSuchAlgorithmException, URISyntaxException, InvalidKeyException, JsonProcessingException {
37+
System.out.println("do something");
38+
SmsResponse data = smsService.sendSms("01030323682", "success!!!");
39+
return new ResponseEntity<>(new MessageWithData(200, true, "nice", data), HttpStatus.OK);
40+
}
41+
42+
@GetMapping("/onlytest")
43+
public void dodo(HttpServletRequest req){
44+
System.out.println("hihi");
45+
}
46+
2447

2548
}

‎src/main/java/team/streetalk/domain/User.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class User extends BaseTime{
1919
@Column(nullable = true, length = 100)
2020
private String password;
2121
@Column(nullable = false, length = 100, unique = true)
22-
private String phoneNum;
22+
private String email;
2323

2424
@ManyToOne
2525
@JoinColumn(name = "location_id")

‎src/main/java/team/streetalk/dto/LoginRequest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
@Setter
99
@Getter
1010
public class LoginRequest {
11-
private String PhoneNum;
11+
private String email;
1212
private String password;
1313
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package team.streetalk.dto.sms;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
8+
@AllArgsConstructor
9+
@NoArgsConstructor
10+
@Setter
11+
@Getter
12+
public class MessagesRequestDto {
13+
private String to;
14+
private String content;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package team.streetalk.dto.sms;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
8+
import java.util.List;
9+
10+
@AllArgsConstructor
11+
@NoArgsConstructor
12+
@Setter
13+
@Getter
14+
public class SmsRequest {
15+
private String type;
16+
private String contentType;
17+
private String countryCode;
18+
private String from;
19+
private String content;
20+
private List<MessagesRequestDto> messages;
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package team.streetalk.dto.sms;
2+
3+
import lombok.*;
4+
5+
import java.sql.Timestamp;
6+
import java.util.List;
7+
8+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
9+
@AllArgsConstructor
10+
@Getter
11+
public class SmsResponse {
12+
private String statusCode;
13+
private String statusName;
14+
private String requestId;
15+
private Timestamp requestTime;
16+
}

‎src/main/java/team/streetalk/jwt/CustomUserDetailService.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ public class CustomUserDetailService implements UserDetailsService {
1515
private final UserRepository userRepository;
1616

1717
@Override
18-
public CustomUserDetails loadUserByUsername(String phoneNum) throws UsernameNotFoundException {
19-
User user = userRepository.findByPhoneNum(phoneNum)
20-
.orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다." + phoneNum));
18+
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
19+
User user = userRepository.findByEmail(email)
20+
.orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다." + email));
2121
System.out.println("build customUser");
2222
return CustomUserDetails.build(user);
2323
}
24-
}
24+
}

‎src/main/java/team/streetalk/jwt/CustomUserDetails.java

+3-6
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
public class CustomUserDetails implements UserDetails {
1616

1717
private Long id;
18-
private Integer phoneNum;
18+
private String email;
1919
private String password;
2020
private boolean enabled;
2121

2222

2323
public static CustomUserDetails build(User user){
2424
return new CustomUserDetails(
2525
user.getId(),
26-
user.getPhoneNum(),
26+
user.getEmail(),
2727
user.getPassword(),
2828
true
2929
);
@@ -42,12 +42,9 @@ public String getPassword() {
4242

4343
@Override
4444
public String getUsername() {
45-
return phoneNum.toString();
45+
return email;
4646
}
4747

48-
public Integer getPhoneNum(){
49-
return phoneNum;
50-
}
5148
@Override
5249
public boolean isAccountNonExpired() {
5350
return true;

‎src/main/java/team/streetalk/jwt/JwtAuthenticationFilter.java

+13-19
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,35 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { // * 클래
2525

2626
@Override
2727
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
28-
final String requestTokenHeader = request.getHeader("Authorization");
29-
30-
String phoneNum = null;
31-
String jwtToken = null;
32-
3328
//토큰에 헤드를 넣어 넘길때 : "Bearer "+ token 으로 만들어서 Authorization: 에 넣어 보내기
34-
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
35-
jwtToken = requestTokenHeader.substring(7);
36-
try {
37-
phoneNum = jwtTokenProvider.getPhoneNumFromToken(jwtToken);
38-
} catch (IllegalArgumentException e) {
39-
System.out.println("Unable to get JWT Token");
40-
}
41-
} else {
42-
logger.warn("JWT Token does not begin with Bearer String");
29+
if(request.getHeader("Authorization") == null){
30+
filterChain.doFilter(request,response);
31+
return;
4332
}
33+
String jwtToken = jwtTokenProvider.resolveToken(request);
34+
String email = jwtTokenProvider.getEmailFromToken(jwtToken);
4435

45-
46-
if(phoneNum != null && SecurityContextHolder.getContext().getAuthentication() == null) {
47-
CustomUserDetails customUserDetails = customUserDetailsService.loadUserByUsername(phoneNum);
36+
if(email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
37+
UserDetails userDetails = customUserDetailsService.loadUserByUsername(email);
4838
try{
49-
if(jwtTokenProvider.validateToken(jwtToken, customUserDetails)) {
39+
if(jwtTokenProvider.validateToken(jwtToken, userDetails)) {
5040
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
51-
customUserDetails, null, customUserDetails.getAuthorities());
41+
userDetails, null, userDetails.getAuthorities());
5242
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
5343
SecurityContextHolder.getContext().setAuthentication(authentication);
5444
}
5545
} catch (Exception ex) {
5646
//this is very important, since it guarantees the user is not authenticated at all
5747
SecurityContextHolder.clearContext();
48+
System.out.println("error in building securityContextholder");
5849
return;
5950
}
6051
}
52+
53+
System.out.println("done filtering");
6154
filterChain.doFilter(request,response);
6255
}
6356

6457

58+
6559
}

‎src/main/java/team/streetalk/jwt/JwtTokenProvider.java

+15-9
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ public class JwtTokenProvider {
2020

2121
@Value("${jwt.secret}")
2222
private String secret;
23-
2423
@PostConstruct
25-
protected void init() {
24+
protected void init(){
2625
secret = Base64.getEncoder().encodeToString(secret.getBytes());
2726
}
2827

@@ -38,7 +37,7 @@ public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver)
3837
return claimsResolver.apply(claims);
3938
}
4039

41-
public String getPhoneNumFromToken(String token) {
40+
public String getEmailFromToken(String token) {
4241
return getClaimFromToken(token, Claims::getSubject);
4342
}
4443

@@ -60,19 +59,26 @@ public String createToken(Authentication authentication) {
6059
.compact();
6160
}
6261

63-
public Boolean validateToken(String token, CustomUserDetails customUserDetails) {
64-
final String PhoneNum = getPhoneNumFromToken(token);
65-
return (PhoneNum.equals(customUserDetails.getUsername())) && !isTokenExpired(token);
62+
public Boolean validateToken(String token, UserDetails userDetails) {
63+
final String email = getEmailFromToken(token);
64+
return (email.equals(userDetails.getUsername())) && !isTokenExpired(token);
6665
}
67-
6866
public String resolveToken(HttpServletRequest req) {
6967
String bearerToken = req.getHeader("Authorization");
7068
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
7169
return bearerToken.substring(7);
72-
} else {
70+
}else {
7371
throw new NullPointerException("Unable to get JWT");
7472
}
73+
}
74+
// public String getUsername(String token) {
75+
// return (String) Jwts
76+
// .parser()
77+
// .setSigningKey(secret)
78+
// .parseClaimsJws(token)
79+
// .getBody()
80+
// .get("name");
81+
// }
7582

7683

77-
}
7884
}

‎src/main/java/team/streetalk/repository/UserRepository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
@Repository
1010
public interface UserRepository extends JpaRepository<User, Long>{
1111

12-
Optional<User> findByPhoneNum(String phoneNum);
12+
Optional<User> findByEmail(String email);
1313

1414

1515
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package team.streetalk.service;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import lombok.AllArgsConstructor;
6+
import org.apache.tomcat.util.codec.binary.Base64;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.beans.factory.annotation.Value;
9+
import org.springframework.http.HttpEntity;
10+
import org.springframework.http.HttpHeaders;
11+
import org.springframework.http.MediaType;
12+
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
13+
import org.springframework.stereotype.Service;
14+
import org.springframework.transaction.annotation.Transactional;
15+
import org.springframework.web.client.RestTemplate;
16+
import team.streetalk.dto.sms.MessagesRequestDto;
17+
import team.streetalk.dto.sms.SmsRequest;
18+
import team.streetalk.dto.sms.SmsResponse;
19+
20+
import javax.crypto.Mac;
21+
import javax.crypto.spec.SecretKeySpec;
22+
import java.io.UnsupportedEncodingException;
23+
import java.net.URI;
24+
import java.net.URISyntaxException;
25+
import java.security.InvalidKeyException;
26+
import java.security.NoSuchAlgorithmException;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
30+
@Service
31+
@Transactional
32+
public class SmsService {
33+
34+
private String serviceId = "ncp:sms:kr:273379428439:streetalk";
35+
private String accessKey = "dQZPT2Sgg1jfNuPInrIR";
36+
private String secretKey = "2gi7xUYug4XGrAd9jwRVO1yi68LiZwNMc3hLPImv";
37+
38+
39+
public SmsResponse sendSms(String recipientPhoneNumber, String content) throws JsonProcessingException, UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, URISyntaxException {
40+
Long time = System.currentTimeMillis();
41+
List<MessagesRequestDto> messages = new ArrayList<>();
42+
messages.add(new MessagesRequestDto(recipientPhoneNumber, content));
43+
SmsRequest smsRequest = new SmsRequest("SMS", "COMM", "82", "01030323682", "MangoLtd", messages);
44+
ObjectMapper objectMapper = new ObjectMapper();
45+
String jsonBody = objectMapper.writeValueAsString(smsRequest);
46+
HttpHeaders headers = new HttpHeaders();
47+
headers.setContentType(MediaType.APPLICATION_JSON);
48+
headers.set("x-ncp-apigw-timestamp", time.toString());
49+
headers.set("x-ncp-iam-access-key", this.accessKey);
50+
String sig = makeSignature(time);
51+
headers.set("x-ncp-apigw-signature-v2", sig);
52+
HttpEntity<String> body = new HttpEntity<>(jsonBody,headers);
53+
RestTemplate restTemplate = new RestTemplate();
54+
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
55+
SmsResponse smsResponse = restTemplate.postForObject(new URI("https://sens.apigw.ntruss.com/sms/v2/services/"+this.serviceId+"/messages"), body, SmsResponse.class);
56+
return smsResponse;
57+
58+
}
59+
public String makeSignature(Long time) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
60+
61+
String space = " "; // one space
62+
String newLine = "\n"; // new line
63+
String method = "POST"; // method
64+
String url = "/sms/v2/services/"+ this.serviceId+"/messages"; // url (include query string)
65+
String timestamp = time.toString(); // current timestamp (epoch)
66+
String accessKey = this.accessKey; // access key id (from portal or Sub Account)
67+
String secretKey = this.secretKey;
68+
69+
String message = new StringBuilder()
70+
.append(method)
71+
.append(space)
72+
.append(url)
73+
.append(newLine)
74+
.append(timestamp)
75+
.append(newLine)
76+
.append(accessKey)
77+
.toString();
78+
79+
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
80+
Mac mac = Mac.getInstance("HmacSHA256");
81+
mac.init(signingKey);
82+
83+
byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
84+
String encodeBase64String = Base64.encodeBase64String(rawHmac);
85+
86+
return encodeBase64String;
87+
}
88+
}

‎src/main/java/team/streetalk/service/UserService.java

+21-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
import team.streetalk.repository.UserRepository;
1818

1919
import javax.servlet.http.HttpServletRequest;
20-
import java.time.LocalDateTime;
21-
import java.util.Comparator;
20+
import java.util.Random;
2221

2322

2423
@Service
@@ -34,7 +33,7 @@ public class UserService {
3433
@Transactional
3534
public LoginResponse login(LoginRequest loginRequest) {
3635
LoginResponse loginResponse = new LoginResponse();
37-
User existUser = userRepository.findByPhoneNum(loginRequest.getPhoneNum())
36+
User existUser = userRepository.findByEmail(loginRequest.getEmail())
3837
.orElseGet(()->signup(loginRequest));
3938
try{
4039
loginResponse.setToken(doGenerateToken(loginRequest));
@@ -47,21 +46,37 @@ public LoginResponse login(LoginRequest loginRequest) {
4746
@Transactional
4847
public User signup(LoginRequest loginRequest) {
4948
User user = new User();
50-
user.setPhoneNum(loginRequest.getPhoneNum());
49+
System.out.println(loginRequest.getEmail());
50+
user.setEmail(loginRequest.getEmail());
5151
user.setPassword(passwordEncoder.encode(loginRequest.getPassword())); //id = email, pwd = loginId
5252
userRepository.save(user);
53+
System.out.println("user build!");
5354
return user;
5455
}
5556

57+
public String getAuthCode() {
58+
Random random = new Random();
59+
StringBuffer buffer = new StringBuffer();
60+
int num = 0;
61+
num = random.nextInt(8) + 1;
62+
buffer.append(num);
63+
while (buffer.length() < 6) {
64+
num = random.nextInt(10);
65+
buffer.append(num);
66+
}
67+
return buffer.toString();
68+
}
69+
70+
5671
public String doGenerateToken(LoginRequest loginRequest) {
5772
Authentication authenticate = authenticationManager.authenticate(
58-
new UsernamePasswordAuthenticationToken(loginRequest.getPhoneNum(), loginRequest.getPassword()));
73+
new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword()));
5974
SecurityContextHolder.getContext().setAuthentication(authenticate);
6075
return jwtTokenProvider.createToken(authenticate);
6176
}
6277

6378
public User getCurrentUser(HttpServletRequest req) {
64-
return userRepository.findByPhoneNum(jwtTokenProvider.getPhoneNumFromToken(jwtTokenProvider.resolveToken(req)))
79+
return userRepository.findByEmail(jwtTokenProvider.getEmailFromToken(jwtTokenProvider.resolveToken(req)))
6580
.orElseThrow(() -> new RuntimeException("can't find who am i"));
6681
}
6782

0 commit comments

Comments
 (0)
Please sign in to comment.