Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions spring-auth-1/complete/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'

implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
package cholog.auth.infrastructure;

import io.jsonwebtoken.*;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtTokenProvider {
@Value("${security.jwt.token.secret-key}")
private String secretKey;
@Value("${security.jwt.token.expire-length}")
private long validityInMilliseconds;
private final Key secretKey;
private final long validityInMilliseconds;

public JwtTokenProvider(
@Value("${security.jwt.token.secret-key}") String rawSecretKey,
@Value("${security.jwt.token.expire-length}") Long validityInMilliseconds
) {
final byte[] keyBytes = Base64.getDecoder().decode(rawSecretKey);
this.secretKey = Keys.hmacShaKeyFor(keyBytes);
this.validityInMilliseconds = validityInMilliseconds;
}


public String createToken(String payload) {
Claims claims = Jwts.claims().setSubject(payload);
Expand All @@ -22,21 +35,30 @@ public String createToken(String payload) {
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.signWith(secretKey)
.compact();
}

public String getPayload(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
validateToken(token);
return Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}

public boolean validateToken(String token) {
private void validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
Jws<Claims> claims = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token);

return !claims.getBody().getExpiration().before(new Date());
claims.getBody().getExpiration();
} catch (JwtException | IllegalArgumentException e) {
return false;
throw new RuntimeException("Invalid token");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Throwing a generic RuntimeException here hides the specific cause of the token validation failure (e.g., expired token, invalid signature). It would be more informative to either throw a more specific exception or re-throw the original caught exception.

Suggested change
throw new RuntimeException("Invalid token");
throw e;

}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public ResponseEntity<TokenResponse> tokenLogin(@RequestBody TokenRequest tokenR
* ex) request sample
* <p>
* GET /members/me/token HTTP/1.1
* authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE2MTAzNzY2NzIsImV4cCI6MTYxMDM4MDI3Mn0.Gy4g5RwK1Nr7bKT1TOFS4Da6wxWh8l97gmMQDgF8c1E
* authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE3NTA0MTY1MzksImV4cCI6MTc1MDQyMDEzOX0.mhaPDrphpRE9mE1YEZreOmDjZCapBrFe-K4SZvXMlAY
* accept: application/json
*/
@GetMapping("/members/me/token")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
security.jwt.token.secret-key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.ih1aovtQShabQ7l0cINw4k1fagApg3qLWiB8Kt59Lno
security.jwt.token.expire-length=3600000
security.jwt.token.secret-key=/BWxvVt/eMsTVSq+RI9kRCrZKK38KNGIWi7ilxCg9So=
security.jwt.token.expire-length=3600000
5 changes: 3 additions & 2 deletions spring-auth-1/initial/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'

implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:5.3.1'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
package cholog.auth.infrastructure;

import io.jsonwebtoken.*;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtTokenProvider {
@Value("${security.jwt.token.secret-key}")
private String secretKey;
@Value("${security.jwt.token.expire-length}")
private long validityInMilliseconds;
private final Key secretKey;
private final long validityInMilliseconds;

public JwtTokenProvider(
@Value("${security.jwt.token.secret-key}") String rawSecretKey,
@Value("${security.jwt.token.expire-length}") Long validityInMilliseconds
) {
final byte[] keyBytes = Base64.getDecoder().decode(rawSecretKey);
this.secretKey = Keys.hmacShaKeyFor(keyBytes);
this.validityInMilliseconds = validityInMilliseconds;
}


public String createToken(String payload) {
Claims claims = Jwts.claims().setSubject(payload);
Expand All @@ -22,21 +35,30 @@ public String createToken(String payload) {
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.signWith(secretKey)
.compact();
}

public String getPayload(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
validateToken(token);
return Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}

public boolean validateToken(String token) {
private void validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
Jws<Claims> claims = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token);

return !claims.getBody().getExpiration().before(new Date());
claims.getBody().getExpiration();
} catch (JwtException | IllegalArgumentException e) {
return false;
throw new RuntimeException("Invalid token");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Throwing a generic RuntimeException here hides the specific cause of the token validation failure (e.g., expired token, invalid signature). It would be more informative to either throw a more specific exception or re-throw the original caught exception.

Suggested change
throw new RuntimeException("Invalid token");
throw e;

}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public ResponseEntity<TokenResponse> tokenLogin() {
* ex) request sample
* <p>
* GET /members/me/token HTTP/1.1
* authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE2MTAzNzY2NzIsImV4cCI6MTYxMDM4MDI3Mn0.Gy4g5RwK1Nr7bKT1TOFS4Da6wxWh8l97gmMQDgF8c1E
* authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlbWFpbEBlbWFpbC5jb20iLCJpYXQiOjE3NTA0MTY1MzksImV4cCI6MTc1MDQyMDEzOX0.mhaPDrphpRE9mE1YEZreOmDjZCapBrFe-K4SZvXMlAY
* accept: application/json
*/
@GetMapping("/members/me/token")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
security.jwt.token.secret-key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.ih1aovtQShabQ7l0cINw4k1fagApg3qLWiB8Kt59Lno
security.jwt.token.expire-length=3600000
security.jwt.token.secret-key=/BWxvVt/eMsTVSq+RI9kRCrZKK38KNGIWi7ilxCg9So=
security.jwt.token.expire-length=3600000