← Back to Main Page

Module 3: Build Sprint 2

Understanding Your Second Ticket

Learn how to approach your second ticket in the Labs project and understand the development workflow.

Second Ticket Details

View your second ticket details and requirements on GitHub:

Second Ticket Documentation

Approaching Your Second Feature

Learn how to implement JWT authentication and RESTful endpoints for the Bloom Coder Assignment App.

Implementation Checklist

  • Add JWT dependency and implement JWT utilities
  • Create JWT filter for request authentication
  • Update Security Configuration for JWT
  • Implement User Repository
  • Update UserDetailsService implementation
  • Configure application properties
  • Implement RESTful endpoints

JWT Implementation Concepts

// Example of JWT token structure and claims
@Component
public class JwtUtil {
    // Token expiration time in seconds
    private static final long EXPIRATION_TIME = 86400000; // 24 hours
    
    // Secret key for signing tokens
    @Value("${jwt.secret}")
    private String secret;

    // Example of how to structure token claims
    public String generateToken(UserDetails userDetails) {
        // Claims are key-value pairs stored in the token
        Map claims = new HashMap<>();
        
        // Example of adding user roles to claims
        claims.put("roles", userDetails.getAuthorities()
                .stream()
                .map(auth -> auth.getAuthority())
                .collect(Collectors.toList()));

        // Token generation with claims
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }
}

Security Configuration Concepts

// Example of configuring security for JWT authentication
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    // Example of JWT filter integration
    @Autowired
    private JwtAuthenticationFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Disable CSRF for API endpoints
        http.csrf().disable();
        
        // Configure stateless session management
        http.sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        
        // Example of public vs protected endpoints
        http.authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated();
        
        // Add JWT filter before username/password authentication
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

RESTful Endpoint Patterns

// Example of RESTful controller structure
@RestController
@RequestMapping("/api/resources")
public class ResourceController {
    
    @Autowired
    private ResourceService resourceService;

    // Example of GET endpoint with response entity
    @GetMapping
    public ResponseEntity> getAllResources() {
        return ResponseEntity.ok(resourceService.findAll());
    }

    // Example of GET with path variable
    @GetMapping("/{id}")
    public ResponseEntity getResourceById(@PathVariable Long id) {
        return ResponseEntity.ok(resourceService.findById(id));
    }

    // Example of POST with request body
    @PostMapping
    public ResponseEntity createResource(@RequestBody Resource resource) {
        return ResponseEntity.ok(resourceService.create(resource));
    }
}

Spring Boot Review

Review essential Spring Boot concepts and JWT authentication implementation for the project.

JWT Utils Implementation

// Example JWT Utils class

@Component
public class JwtUtils {
    @Value("${jwt.secret}")
    private String jwtSecret;
    
    @Value("${jwt.expiration}")
    private int jwtExpirationMs;
    
    public String generateJwtToken(Authentication authentication) {
        UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
        
        return Jwts.builder()
            .setSubject((userPrincipal.getUsername()))
            .setIssuedAt(new Date())
            .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
            .signWith(SignatureAlgorithm.HS512, jwtSecret)
            .compact();
    }
    
    public String getUserNameFromJwtToken(String token) {
        return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
    }
    
    public boolean validateJwtToken(String authToken) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
            return true;
        } catch (SignatureException e) {
            // Handle invalid JWT signature
        } catch (MalformedJwtException e) {
            // Handle invalid JWT token
        } catch (ExpiredJwtException e) {
            // Handle expired JWT token
        } catch (UnsupportedJwtException e) {
            // Handle unsupported JWT token
        } catch (IllegalArgumentException e) {
            // Handle JWT claims string is empty
        }
        return false;
    }
}

Spring Data JPA Repository Example

// Example Repository interface

@Repository
public interface UserRepository extends JpaRepository {
    Optional findByUsername(String username);
    Boolean existsByUsername(String username);
    Boolean existsByEmail(String email);
}

// Example Service implementation
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    public User createUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }
    
    public Optional findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
}