From 4b21828510472507fa46a0657d6cd2706dd07205 Mon Sep 17 00:00:00 2001 From: Kshitij <160704796+kshitij-ka@users.noreply.github.com> Date: Thu, 3 Jul 2025 02:38:55 +0530 Subject: [PATCH] Add JWT-based login and logout endpoints - POST /api/auth/login authenticates user and returns JWT token. - POST /api/auth/logout is a placeholder (client deletes token). - JwtService handles token creation and expiry validation. --- .../controller/AuthController.java | 70 +++++++------------ .../skycrateBackend/dto/LoginRequest.java | 8 +++ .../skycrateBackend/security/JwtService.java | 43 ++++++++++++ 3 files changed, 78 insertions(+), 43 deletions(-) create mode 100644 src/main/java/com/skycrate/backend/skycrateBackend/dto/LoginRequest.java create mode 100644 src/main/java/com/skycrate/backend/skycrateBackend/security/JwtService.java diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/controller/AuthController.java b/src/main/java/com/skycrate/backend/skycrateBackend/controller/AuthController.java index dd100bf..b823bd4 100644 --- a/src/main/java/com/skycrate/backend/skycrateBackend/controller/AuthController.java +++ b/src/main/java/com/skycrate/backend/skycrateBackend/controller/AuthController.java @@ -1,58 +1,42 @@ package com.skycrate.backend.skycrateBackend.controller; -import org.springframework.web.bind.annotation.RestController; - -import com.skycrate.backend.skycrateBackend.dto.LoginUserDto; -import com.skycrate.backend.skycrateBackend.dto.RegisterUserDto; -import com.skycrate.backend.skycrateBackend.models.User; -import com.skycrate.backend.skycrateBackend.responses.LoginResponse; -import com.skycrate.backend.skycrateBackend.services.AuthenticationService; -import com.skycrate.backend.skycrateBackend.services.JwtService; - -import org.springframework.beans.factory.annotation.Autowired; +import com.skycrate.backend.skycrateBackend.dto.LoginRequest; +import com.skycrate.backend.skycrateBackend.security.JwtService; +import com.skycrate.backend.skycrateBackend.entity.User; +import com.skycrate.backend.skycrateBackend.repository.UserRepository; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.web.bind.annotation.*; - -@RequestMapping("/api") @RestController +@RequestMapping("/api/auth") public class AuthController { - + + private final AuthenticationManager authManager; private final JwtService jwtService; - private AuthenticationService authenticationService; + private final UserRepository userRepository; - public AuthController(JwtService jwtService,AuthenticationService authenticationService){ - this.jwtService=jwtService; - this.authenticationService=authenticationService; + public AuthController(AuthenticationManager authManager, JwtService jwtService, UserRepository userRepository) { + this.authManager = authManager; + this.jwtService = jwtService; + this.userRepository = userRepository; } - @GetMapping("/test") - public String teString(@RequestParam String param) { - return new String(); - } - @PostMapping("/login") - public ResponseEntity LoginController(@RequestBody LoginUserDto entity) { + public ResponseEntity login(@RequestBody LoginRequest request) { + authManager.authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword())); - User authenticatedUser=authenticationService.authenticate(entity); - String jwtToken=jwtService.generateToken(authenticatedUser); - - LoginResponse loginResponse=new LoginResponse().setToken(jwtToken).setExpiresIn(jwtService.getExpirtationTime()); - return ResponseEntity.ok(loginResponse); + User user = userRepository.findByEmail(request.getEmail()) + .orElseThrow(() -> new RuntimeException("User not found")); + + String token = jwtService.generateToken(user); + return ResponseEntity.ok().body(token); } - - @PostMapping("/signup") - public ResponseEntity register(@RequestBody RegisterUserDto entity) { - User registeredUser=authenticationService.signUp(entity); - - return ResponseEntity.ok(registeredUser); + @PostMapping("/logout") + public ResponseEntity logout() { + // Client-side token deletion (or implement blacklist) + return ResponseEntity.ok("Logged out (client should delete token)"); } - - - -} +} \ No newline at end of file diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/dto/LoginRequest.java b/src/main/java/com/skycrate/backend/skycrateBackend/dto/LoginRequest.java new file mode 100644 index 0000000..edf52ae --- /dev/null +++ b/src/main/java/com/skycrate/backend/skycrateBackend/dto/LoginRequest.java @@ -0,0 +1,8 @@ +package com.skycrate.backend.skycrateBackend.dto; + +public class LoginRequest { + private String email; + private String password; + + // Getters and setters +} diff --git a/src/main/java/com/skycrate/backend/skycrateBackend/security/JwtService.java b/src/main/java/com/skycrate/backend/skycrateBackend/security/JwtService.java new file mode 100644 index 0000000..0e6ef04 --- /dev/null +++ b/src/main/java/com/skycrate/backend/skycrateBackend/security/JwtService.java @@ -0,0 +1,43 @@ +package com.skycrate.backend.skycrateBackend.security; + +import com.skycrate.backend.skycrateBackend.entity.User; +import io.jsonwebtoken.*; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Service; + +import java.security.Key; +import java.util.Date; + +@Service +public class JwtService { + + private static final String SECRET = "super-secret-256-bit-key-which-you-should-keep-safe!"; + private static final long EXPIRATION_MS = 1000 * 60 * 60; // 1 hour + + private final Key key = Keys.hmacShaKeyFor(SECRET.getBytes()); + + public String generateToken(User user) { + return Jwts.builder() + .setSubject(user.getEmail()) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_MS)) + .signWith(key) + .compact(); + } + + public String extractUsername(String token) { + return Jwts.parserBuilder().setSigningKey(key).build() + .parseClaimsJws(token) + .getBody().getSubject(); + } + + public boolean isTokenValid(String token, User user) { + return extractUsername(token).equals(user.getEmail()) && !isTokenExpired(token); + } + + public boolean isTokenExpired(String token) { + return Jwts.parserBuilder().setSigningKey(key).build() + .parseClaimsJws(token) + .getBody().getExpiration().before(new Date()); + } +} \ No newline at end of file