top of page
Search

JWT controller starter

```java

package com.example.demo.controller;


import com.example.demo.payload.request.LoginRequest;

import com.example.demo.payload.request.SignupRequest;

import com.example.demo.payload.response.MessageResponse;

import com.example.demo.payload.response.UserInfoResponse;

import com.example.demo.payload.response.UserResponse;

import com.example.demo.security.jwt.JwtUtils;

import com.example.demo.security.services.UserDetailsImpl;

import com.example.demo.service.UserService; // Assuming you have a UserService


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.security.authentication.AuthenticationManager;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.core.Authentication;

import org.springframework.security.core.context.SecurityContextHolder;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.security.crypto.password.PasswordEncoder;

import org.springframework.web.bind.annotation.*;


import java.util.List;

import java.util.stream.Collectors;


@CrossOrigin(origins = "*", maxAge = 3600)

@RestController

@RequestMapping("/api/auth")

public class AuthController {


    @Autowired

    AuthenticationManager authenticationManager;


    @Autowired

    UserService userService; // Assuming you have a UserService for user management


    @Autowired

    PasswordEncoder encoder;


    @Autowired

    JwtUtils jwtUtils;


    @PostMapping("/signin")

    public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {


        Authentication authentication = authenticationManager.authenticate(

                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));


        SecurityContextHolder.getContext().setAuthentication(authentication);


        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();


        String jwt = jwtUtils.generateJwtToken(userDetails);


        List<String> roles = userDetails.getAuthorities().stream()

                .map(item -> item.getAuthority())

                .collect(Collectors.toList());


        return ResponseEntity.ok(new UserInfoResponse(jwt,

                userDetails.getId(),

                userDetails.getUsername(),

                userDetails.getEmail(),

                roles));

    }


    @PostMapping("/signup")

    public ResponseEntity<?> registerUser(@RequestBody SignupRequest signUpRequest) {

        if (userService.existsByUsername(signUpRequest.getUsername())) {

            return ResponseEntity

                    .badRequest()

                    .body(new MessageResponse("Error: Username is already taken!"));

        }


        if (userService.existsByEmail(signUpRequest.getEmail())) {

            return ResponseEntity

                    .badRequest()

                    .body(new MessageResponse("Error: Email is already in use!"));

        }


        userService.registerNewUser(signUpRequest); // Assuming this method handles user creation and role assignment


        return ResponseEntity.ok(new MessageResponse("User registered successfully!"));

    }


    @PostMapping("/signout")

    public ResponseEntity<?> logoutUser() {

        // In a stateless JWT environment, server-side sign-out is often not strictly necessary.

        // The client typically discards the token.

        // You might want to implement token blacklisting or refresh token invalidation if needed.

        // For this basic example, we just return a success message.

        return ResponseEntity.ok(new MessageResponse("You've been signed out!"));

    }


    @GetMapping("/username")

    public ResponseEntity<String> getCurrentUsername() {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {

            UserDetails userDetails = (UserDetails) authentication.getPrincipal();

            return ResponseEntity.ok(userDetails.getUsername());

        }

        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

    }


    @GetMapping("/user")

    public ResponseEntity<?> getUserInfo() {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication != null && authentication.getPrincipal() instanceof UserDetailsImpl) {

            UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();

            List<String> roles = userDetails.getAuthorities().stream()

                    .map(item -> item.getAuthority())

                    .collect(Collectors.toList());

            return ResponseEntity.ok(new UserInfoResponse(null, // No need to send JWT again

                    userDetails.getId(),

                    userDetails.getUsername(),

                    userDetails.getEmail(),

                    roles));

        }

        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();

    }


    @GetMapping("/sellers")

    public ResponseEntity<List<UserResponse>> getAllSellers(@RequestParam(defaultValue = "0") int pageNumber) {

        // Assuming your UserService has a method to fetch sellers with pagination

        List<UserResponse> sellers = userService.getAllSellers(pageNumber);

        return ResponseEntity.ok(sellers);

    }

}

```


Explanation of the Controller:


1.  `@RestController`: Indicates that this class is a REST controller.

2.  `@RequestMapping("/api/auth")`: Maps all the handler methods in this controller to the `/api/auth` base path.

3.  **`@CrossOrigin(origins = "*", maxAge = 3600)`**: Enables Cross-Origin Resource Sharing (CORS) from all origins for up to 3600 seconds. You might want to restrict this in a production environment.

4.  `@Autowired`: Used for dependency injection of the required beans:

    * `AuthenticationManager`: For authenticating user credentials.

    * `UserService`: A service layer component (you'll need to create this) responsible for user-related operations like checking for existing users and saving new users, and fetching sellers.

    * `PasswordEncoder`: For encoding passwords.

    * `JwtUtils`: Our utility class for JWT operations.

5.  `@PostMapping("/signin")`: Handles the `/signin` POST request.

    * It authenticates the user using the `AuthenticationManager` with the provided username and password from the `LoginRequest`.

    * If authentication is successful, it retrieves the `UserDetailsImpl` (your custom UserDetails implementation).

    * It generates a JWT using `JwtUtils`.

    * It extracts the user's roles.

    * It returns a `UserInfoResponse` containing the JWT and user information with an HTTP 200 OK status.

6.  `@PostMapping("/signup")`: Handles the `/signup` POST request.

    * It checks if a user with the given username or email already exists using the `UserService`.

    * If either exists, it returns a bad request with an error message.

    * Otherwise, it calls the `userService.registerNewUser()` method (you'll need to implement this in your service layer) to create the new user.

    * It returns a success message with an HTTP 200 OK status.

7.  `@PostMapping("/signout")`: Handles the `/signout` POST request.

    * In a stateless JWT setup, the server doesn't usually maintain sessions. Signing out typically involves the client discarding the JWT. This endpoint simply acknowledges the request with a success message. You might add more complex logic here if you implement token blacklisting or refresh tokens.

8.  `@GetMapping("/username")`: Handles the `/username` GET request.

    * It retrieves the authentication object from the `SecurityContextHolder`.

    * If the user is authenticated, it extracts the username from the `UserDetails` and returns it with an HTTP 200 OK status.

    * If not authenticated, it returns an HTTP 401 Unauthorized status.

9.  `@GetMapping("/user")`: Handles the `/user` GET request.

    * Similar to `/username`, it retrieves the authenticated user's details (`UserDetailsImpl`) and returns a `UserInfoResponse` (without the JWT in this case) with an HTTP 200 OK status.

    * Returns HTTP 401 if not authenticated.

10. `@GetMapping("/sellers")`: Handles the `/sellers` GET request.

    * It takes an optional `pageNumber` as a query parameter (defaulting to 0).

    * It calls the `userService.getAllSellers()` method (you'll need to implement this in your service layer to fetch sellers with pagination) and returns the list of `UserResponse` objects with an HTTP 200 OK status.


Remember to create the following:


*`com.example.demo.payload.request.LoginRequest`**: A class to hold the username and password for login.

*`com.example.demo.payload.request.SignupRequest`**: A class to hold the registration details (username, email, password, roles, etc.).

*`com.example.demo.payload.response.MessageResponse`**: A simple class to hold a message (e.g., for signup success or errors).

*`com.example.demo.payload.response.UserInfoResponse`**: A class to hold the JWT, user ID, username, email, and roles.

*`com.example.demo.payload.response.UserResponse`**: A class to hold the basic information of a user (e.g., ID, username, email, roles) for the `/sellers` endpoint.

*`com.example.demo.service.UserService`**: An interface and its implementation to handle user-related business logic (checking for existing users, saving new users, fetching users by username/email, fetching sellers with pagination, etc.). You'll need to interact with your data access layer (e.g., Spring Data JPA repositories) within this service.

Ensure your `SecurityConfig` is set up to allow access to `/api/auth/*` without authentication for the signup and signin endpoints.


This controller provides the basic endpoints you requested for authentication and user information retrieval in your Spring Boot application secured with JWT. You'll need to implement the corresponding service layer and data access logic to make it fully functional.

 
 
 

Recent Posts

See All

Comentarios


Post: Blog2_Post

Subscribe Form

Thanks for submitting!

©2020 by LearnTeachMaster DevOps. Proudly created with Wix.com

bottom of page