Skip to content

Commit 58cef4e

Browse files
Rajeev Kumar Singhcallicoder
Rajeev Kumar Singh
authored andcommitted
Using RefreshToken
1 parent de3ccdc commit 58cef4e

File tree

7 files changed

+149
-13
lines changed

7 files changed

+149
-13
lines changed

polling-app-server/src/main/java/com/example/polls/controller/AuthController.java

+43-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
package com.example.polls.controller;
22

33
import com.example.polls.exception.AppException;
4+
import com.example.polls.exception.BadRequestException;
5+
import com.example.polls.model.JwtRefreshToken;
46
import com.example.polls.model.Role;
57
import com.example.polls.model.RoleName;
68
import com.example.polls.model.User;
7-
import com.example.polls.payload.ApiResponse;
8-
import com.example.polls.payload.JwtAuthenticationResponse;
9-
import com.example.polls.payload.LoginRequest;
10-
import com.example.polls.payload.SignUpRequest;
9+
import com.example.polls.payload.*;
10+
import com.example.polls.repository.RefreshTokenRepository;
1111
import com.example.polls.repository.RoleRepository;
1212
import com.example.polls.repository.UserRepository;
1313
import com.example.polls.security.JwtTokenProvider;
14+
import com.example.polls.security.UserPrincipal;
1415
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.beans.factory.annotation.Value;
1517
import org.springframework.http.HttpStatus;
1618
import org.springframework.http.ResponseEntity;
1719
import org.springframework.security.authentication.AuthenticationManager;
@@ -27,6 +29,8 @@
2729

2830
import javax.validation.Valid;
2931
import java.net.URI;
32+
import java.time.Instant;
33+
import java.time.temporal.ChronoUnit;
3034
import java.util.Collections;
3135

3236
/**
@@ -51,6 +55,12 @@ public class AuthController {
5155
@Autowired
5256
JwtTokenProvider tokenProvider;
5357

58+
@Autowired
59+
RefreshTokenRepository refreshTokenRepository;
60+
61+
@Value("${app.jwtExpirationInMs}")
62+
private long jwtExpirationInMs;
63+
5464
@PostMapping("/signin")
5565
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
5666

@@ -63,8 +73,35 @@ public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest login
6373

6474
SecurityContextHolder.getContext().setAuthentication(authentication);
6575

66-
String jwt = tokenProvider.generateToken(authentication);
67-
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
76+
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
77+
78+
String accessToken = tokenProvider.generateToken(userPrincipal);
79+
String refreshToken = tokenProvider.generateRefreshToken();
80+
81+
saveRefreshToken(userPrincipal, refreshToken);
82+
83+
return ResponseEntity.ok(new JwtAuthenticationResponse(accessToken, refreshToken, jwtExpirationInMs));
84+
}
85+
86+
@PostMapping("/refreshToken")
87+
public ResponseEntity<?> refreshAccessToken(@Valid @RequestBody RefreshTokenRequest refreshTokenRequest) {
88+
return refreshTokenRepository.findById(refreshTokenRequest.getRefreshToken()).map(jwtRefreshToken -> {
89+
User user = jwtRefreshToken.getUser();
90+
String accessToken = tokenProvider.generateToken(UserPrincipal.create(user));
91+
return ResponseEntity.ok(new JwtAuthenticationResponse(accessToken, jwtRefreshToken.getToken(), jwtExpirationInMs));
92+
}).orElseThrow(() -> new BadRequestException("Invalid Refresh Token"));
93+
}
94+
95+
private void saveRefreshToken(UserPrincipal userPrincipal, String refreshToken) {
96+
// Persist Refresh Token
97+
98+
JwtRefreshToken jwtRefreshToken = new JwtRefreshToken(refreshToken);
99+
jwtRefreshToken.setUser(userRepository.getOne(userPrincipal.getId()));
100+
101+
Instant expirationDateTime = Instant.now().plus(360, ChronoUnit.DAYS); // Todo Add this in application.properties
102+
jwtRefreshToken.setExpirationDateTime(expirationDateTime);
103+
104+
refreshTokenRepository.save(jwtRefreshToken);
68105
}
69106

70107
@PostMapping("/signup")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.example.polls.model;
2+
3+
import javax.persistence.*;
4+
import java.time.Instant;
5+
6+
@Entity
7+
@Table(name = "refresh_tokens")
8+
public class JwtRefreshToken {
9+
@Id
10+
private String token;
11+
12+
@ManyToOne(fetch = FetchType.LAZY)
13+
@JoinColumn(name = "user_id", nullable = false)
14+
private User user;
15+
16+
private Instant expirationDateTime;
17+
18+
public JwtRefreshToken() {
19+
20+
}
21+
22+
public JwtRefreshToken(String token) {
23+
this.token = token;
24+
}
25+
26+
public String getToken() {
27+
return token;
28+
}
29+
30+
public void setToken(String token) {
31+
this.token = token;
32+
}
33+
34+
public User getUser() {
35+
return user;
36+
}
37+
38+
public void setUser(User user) {
39+
this.user = user;
40+
}
41+
42+
public Instant getExpirationDateTime() {
43+
return expirationDateTime;
44+
}
45+
46+
public void setExpirationDateTime(Instant expirationDateTime) {
47+
this.expirationDateTime = expirationDateTime;
48+
}
49+
}

polling-app-server/src/main/java/com/example/polls/payload/JwtAuthenticationResponse.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,22 @@
55
*/
66
public class JwtAuthenticationResponse {
77
private String accessToken;
8+
private String refreshToken;
89
private String tokenType = "Bearer";
10+
private Long expiresInMsec;
911

10-
public JwtAuthenticationResponse(String accessToken) {
12+
public JwtAuthenticationResponse(String accessToken, String refreshToken, Long expiresInMsec) {
1113
this.accessToken = accessToken;
14+
this.refreshToken = refreshToken;
15+
this.expiresInMsec = expiresInMsec;
16+
}
17+
18+
public String getRefreshToken() {
19+
return refreshToken;
20+
}
21+
22+
public void setRefreshToken(String refreshToken) {
23+
this.refreshToken = refreshToken;
1224
}
1325

1426
public String getAccessToken() {
@@ -26,4 +38,12 @@ public String getTokenType() {
2638
public void setTokenType(String tokenType) {
2739
this.tokenType = tokenType;
2840
}
41+
42+
public Long getExpiresInMsec() {
43+
return expiresInMsec;
44+
}
45+
46+
public void setExpiresInMsec(Long expiresInMsec) {
47+
this.expiresInMsec = expiresInMsec;
48+
}
2949
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.example.polls.payload;
2+
3+
import javax.validation.constraints.NotBlank;
4+
5+
public class RefreshTokenRequest {
6+
@NotBlank
7+
private String refreshToken;
8+
9+
public String getRefreshToken() {
10+
return refreshToken;
11+
}
12+
13+
public void setRefreshToken(String refreshToken) {
14+
this.refreshToken = refreshToken;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.example.polls.repository;
2+
3+
import com.example.polls.model.JwtRefreshToken;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
@Repository
8+
public interface RefreshTokenRepository extends JpaRepository<JwtRefreshToken, String> {
9+
10+
}

polling-app-server/src/main/java/com/example/polls/security/JwtTokenProvider.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.springframework.stereotype.Component;
99

1010
import java.util.Date;
11+
import java.util.UUID;
1112

1213
/**
1314
* Created by rajeevkumarsingh on 19/08/17.
@@ -21,12 +22,9 @@ public class JwtTokenProvider {
2122
private String jwtSecret;
2223

2324
@Value("${app.jwtExpirationInMs}")
24-
private int jwtExpirationInMs;
25-
26-
public String generateToken(Authentication authentication) {
27-
28-
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
25+
private long jwtExpirationInMs;
2926

27+
public String generateToken(UserPrincipal userPrincipal) {
3028
Date now = new Date();
3129
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
3230

@@ -38,6 +36,11 @@ public String generateToken(Authentication authentication) {
3836
.compact();
3937
}
4038

39+
public String generateRefreshToken() {
40+
// generate a random UUID as refresh token
41+
return UUID.randomUUID().toString();
42+
}
43+
4144
public Long getUserIdFromJWT(String token) {
4245
Claims claims = Jwts.parser()
4346
.setSigningKey(jwtSecret)

polling-app-server/src/main/resources/application.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ spring.jackson.time-zone= UTC
2525

2626
## App Properties
2727
app.jwtSecret= JWTSuperSecretKey
28-
app.jwtExpirationInMs = 604800000
28+
#app.jwtExpirationInMs = 604800000
29+
app.jwtExpirationInMs = 60000
2930

3031
## Spring Profiles
3132
# spring.profiles.active=prod

0 commit comments

Comments
 (0)