Index: my-react-app/src/axios_helper.js
===================================================================
--- my-react-app/src/axios_helper.js	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ my-react-app/src/axios_helper.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -4,5 +4,18 @@
 axios.defaults.headers.post["Content-Type"] = 'application/json'
 
+export const getAuthToken = () => {
+    return window.localStorage.getItem("auth_token");
+}
+
+export const setAuthToken = (token) => {
+    window.localStorage.setItem("auth_token", token);
+}
+
 export const request = (method, url, data) => {
+    let headers = {};
+    if(getAuthToken() !== null && getAuthToken() !== "null") {
+        headers = {"Authorization" : `Bearer ${getAuthToken()}`};
+    }
+
     return axios({
         method: method,
Index: my-react-app/src/components/AppContent.js
===================================================================
--- my-react-app/src/components/AppContent.js	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ my-react-app/src/components/AppContent.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -2,11 +2,64 @@
 import WelcomeContent from "./WelcomeContent";
 import AuthContent from "./AuthContent";
+import LoginForm from "./LoginForm";
+import { request, setAuthToken } from "../axios_helper";
+import Buttons from './Buttons'
 
 export default class AppContent extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            componentToShow: "welcome"
+        };
+    };
+
+    login = () => {
+        this.setState({componentToShow: "login"})
+    }
+
+    logout = () => {
+        this.setState({componentToShow: "welcome"})
+    }
+
+    onLogin = (e, email, password) => {
+        e.preventDefault();
+        request(
+            "POST",
+            "/api/login",
+            {login: email, password: password}
+        ).then((response) => {
+            this.setState({componentToShow: "restaurants"})
+            setAuthToken(response.data.token);
+        }).catch((error) => {
+            this.setState({componentToShow: "welcome"})
+        });
+    };
+
+    onRegister = (e, firstName, lastName, email, password) => {
+        e.preventDefault();
+        request(
+            "POST",
+            "/api/register",
+            {
+                firstName: firstName,
+                lastName: lastName,
+                login: email,
+                password: password
+            }
+        ).then((response) => {
+            this.setState({componentToShow: "restaurants"})
+            setAuthToken(response.data.token);
+        }).catch((error) => {
+            this.setState({componentToShow: "welcome"})
+        });
+    };
+
     render() {
         return (
             <div>
-                <WelcomeContent/>
-                <AuthContent/>
+                <Buttons login={this.login} logout={this.logout}></Buttons>
+                {this.state.componentToShow === "welcome" && <WelcomeContent/>}
+                {this.state.componentToShow === "restaurants" && <AuthContent/>}
+                {this.state.componentToShow === "login" && <LoginForm onLogin={this.onLogin} onRegister={this.onRegister}/>}
             </div>
         )
Index: my-react-app/src/components/Buttons.js
===================================================================
--- my-react-app/src/components/Buttons.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ my-react-app/src/components/Buttons.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,12 @@
+import * as React from "react";
+
+export default function Buttons(props) {
+    return (
+        <div className="row">
+            <div className="col-md-12 text-center" style={{marginTop:"30px"}}>
+                <button onClick={props.login}>Login</button>
+                <button onClick={props.logout}>Logout</button>
+            </div>
+        </div>
+    )
+}
Index: my-react-app/src/components/LoginForm.js
===================================================================
--- my-react-app/src/components/LoginForm.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ my-react-app/src/components/LoginForm.js	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,100 @@
+import * as React from "react";
+import bootstrap from 'bootstrap/dist/css/bootstrap.min.css'
+import classNames from 'classnames';
+
+export default class LoginForm extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            active: "login",
+            firstName: "",
+            lastName: "",
+            email: "",
+            password: "",
+            onLogin: props.onLogin,
+            onRegister: props.onRegister
+        }
+    }
+
+    onChangeHandler = (e) => {
+        let name = e.target.name;
+        let value = e.target.value;
+        this.setState({[name]: value})
+    }
+
+    onSubmitLogin = (e) => {
+        this.state.onLogin(e, this.state.email, this.state.password);
+    }
+
+    onSubmitRegister = (e) => {
+        this.state.onRegister(
+            e,
+            this.state.firstName,
+            this.state.lastName,
+            this.state.email,
+            this.state.password)
+    }
+
+    render() {
+        return (
+            <div className="row justify-content-center">
+                <div className="col-4">
+                    <ul className="nav nav-pills nav-justified mb-3" id="ex1" role="tablist">
+                        <li className="nav-item" role="presentation">
+                            <button className={classNames("nav-link", this.state.active === "login" ? "active" : "")}
+                                    id="tab-login" onClick={() => this.setState({active: "login"})}>Login
+                            </button>
+                        </li>
+                        <li className="nav-item" role="presentation">
+                            <button className={classNames("nav-link", this.state.active === "register" ? "active" : "")}
+                                    id="tab-register" onClick={() => this.setState({active: "register"})}>Register
+                            </button>
+                        </li>
+                    </ul>
+
+                    <div className="tab-content">
+                        <div
+                            className={classNames("tab-pane", "fade", this.state.active === "login" ? "show active" : "")} id="pills-login">
+                            <form onSubmit={this.onSubmitLogin}>
+                                <div className="form-outline mb-4">
+                                    <input type="login" id="loginEmail" name="login" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="loginEmail">Email</label>
+                                </div>
+                                <div className="form-outline mb-4">
+                                    <input type="password" id="loginPassword" name="password" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="loginPassword">Password</label>
+                                </div>
+
+                                <button type="submit" className="btn btn-primary btn-block mb-4">Sign In</button>
+                            </form>
+                        </div>
+
+                        <div
+                            className={classNames("tab-pane", "fade", this.state.active === "register" ? "show active" : "")} id="pills-register">
+                            <form onSubmit={this.onSubmitRegister}>
+                                <div className="form-outline mb-4">
+                                    <input type="text" id="firstName" name="firstName" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="firstName">First Name</label>
+                                </div>
+                                <div className="form-outline mb-4">
+                                    <input type="text" id="lastName" name="lastName" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="lastName">Last Name</label>
+                                </div>
+                                <div className="form-outline mb-4">
+                                    <input type="text" id="email" name="email" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="email">Email</label>
+                                </div>
+                                <div className="form-outline mb-4">
+                                    <input type="password" id="loginPassword" name="password" className="form-control" onChange={this.onChangeHandler}/>
+                                    <label className="form-label" htmlFor="loginPassword">Password</label>
+                                </div>
+
+                                <button type="submit" className="btn btn-primary btn-block mb-4">Sign In</button>
+                            </form>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        )
+    }
+}
Index: pom.xml
===================================================================
--- pom.xml	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ pom.xml	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -99,6 +99,12 @@
 		<dependency>
 			<groupId>org.mapstruct</groupId>
-			<artifactId>mapstruct-processor</artifactId>
-			<version>1.5.3.Final</version>
+			<artifactId>mapstruct</artifactId>
+			<version>1.4.2.Final</version> <!-- Replace with the latest version -->
+		</dependency>
+
+		<dependency>
+			<groupId>com.auth0</groupId>
+			<artifactId>java-jwt</artifactId>
+			<version>4.3.0</version>
 		</dependency>
 	</dependencies>
Index: src/main/java/com/example/rezevirajmasa/demo/config/PasswordEncoder.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/config/PasswordEncoder.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/config/PasswordEncoder.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,13 @@
+package com.example.rezevirajmasa.demo.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PasswordEncoder {
+    @Bean
+    public org.springframework.security.crypto.password.PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/config/RestExceptionHandler.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/config/RestExceptionHandler.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/config/RestExceptionHandler.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,18 @@
+package com.example.rezevirajmasa.demo.config;
+
+import com.example.rezevirajmasa.demo.dto.ErrorDto;
+import com.example.rezevirajmasa.demo.model.exceptions.AppException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@ControllerAdvice
+public class RestExceptionHandler {
+    @ExceptionHandler(value = {AppException.class})
+    @ResponseBody
+    public ResponseEntity<ErrorDto> handleException(AppException ex) {
+        return ResponseEntity.status(ex.getCode())
+                .body(ErrorDto.builder().message(ex.getMessage()).build());
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/config/SecurityConfig.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/config/SecurityConfig.java	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ src/main/java/com/example/rezevirajmasa/demo/config/SecurityConfig.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -1,6 +1,9 @@
 package com.example.rezevirajmasa.demo.config;
 
+import com.example.rezevirajmasa.demo.model.exceptions.CustomerAuthenticationEntryPoint;
+import com.example.rezevirajmasa.demo.web.filters.JwtAuthFilter;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
@@ -9,13 +12,10 @@
 import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
 import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
 
 @Configuration
@@ -23,7 +23,11 @@
 public class SecurityConfig implements WebMvcConfigurer {
     private final UserDetailsService userDetailsService;
+    private final CustomerAuthenticationEntryPoint customerAuthenticationEntryPoint;
+    private final UserAuthProvider userAuthProvider;
 
-    public SecurityConfig(UserDetailsService userDetailsService) {
+    public SecurityConfig(UserDetailsService userDetailsService, CustomerAuthenticationEntryPoint customerAuthenticationEntryPoint, UserAuthProvider userAuthProvider) {
         this.userDetailsService = userDetailsService;
+        this.customerAuthenticationEntryPoint = customerAuthenticationEntryPoint;
+        this.userAuthProvider = userAuthProvider;
     }
 
@@ -43,31 +47,44 @@
     }
 
+//    @Bean
+//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception  {
+//
+//        http
+//                .csrf(AbstractHttpConfigurer::disable)
+//                .authorizeHttpRequests( (requests) -> requests
+//                        .requestMatchers(AntPathRequestMatcher.antMatcher("/"), AntPathRequestMatcher.antMatcher("/restaurants"))
+//                        .permitAll()
+//                        .anyRequest()
+//                        .hasAnyRole("ADMIN", "USER")
+//                )
+//                .formLogin((form) -> form
+//                        .permitAll()
+//                        .failureUrl("/login?error=BadCredentials")
+//                        .defaultSuccessUrl("/restaurants", true)
+//                )
+//                .logout((logout) -> logout
+//                        .logoutUrl("/logout")
+//                        .clearAuthentication(true)
+//                        .invalidateHttpSession(true)
+//                        .deleteCookies("JSESSIONID")
+//                        .logoutSuccessUrl("/")
+//                );
+//
+//        return http.build();
+//    }
+
     @Bean
-    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception  {
-
+    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         http
+                .exceptionHandling((exception) -> exception.authenticationEntryPoint(customerAuthenticationEntryPoint))
+                .addFilterBefore(new JwtAuthFilter(userAuthProvider), BasicAuthenticationFilter.class)
                 .csrf(AbstractHttpConfigurer::disable)
-                .authorizeHttpRequests( (requests) -> requests
-                        .requestMatchers(AntPathRequestMatcher.antMatcher("/"), AntPathRequestMatcher.antMatcher("/restaurants"))
-                        .permitAll()
-                        .anyRequest()
-                        .hasAnyRole("ADMIN", "USER")
-                )
-                .formLogin((form) -> form
-                        .permitAll()
-                        .failureUrl("/login?error=BadCredentials")
-                        .defaultSuccessUrl("/restaurants", true)
-                )
-                .logout((logout) -> logout
-                        .logoutUrl("/logout")
-                        .clearAuthentication(true)
-                        .invalidateHttpSession(true)
-                        .deleteCookies("JSESSIONID")
-                        .logoutSuccessUrl("/")
+                .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+                .authorizeHttpRequests((requests) -> requests
+                        .requestMatchers(HttpMethod.POST, "/api/login", "/api/register").permitAll()
+                        .anyRequest().authenticated()
                 );
-
         return http.build();
     }
-
     @Bean
     public AuthenticationManager authManager(HttpSecurity http) throws Exception {
Index: src/main/java/com/example/rezevirajmasa/demo/config/UserAuthProvider.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/config/UserAuthProvider.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/config/UserAuthProvider.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,52 @@
+package com.example.rezevirajmasa.demo.config;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.example.rezevirajmasa.demo.dto.UserDto;
+import com.example.rezevirajmasa.demo.service.UserService;
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import java.util.Base64;
+import java.util.Collections;
+import java.util.Date;
+
+@RequiredArgsConstructor
+@Component
+public class UserAuthProvider {
+    @Value("${security.jwt.token.secret-key:secret:value}")
+    private String secretKey;
+
+    private final UserService userService;
+
+    @PostConstruct
+    protected void init() {
+        secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
+    }
+
+    public String createToken(String login) {
+        Date now = new Date();
+        Date validity = new Date(now.getTime() + 3_600_000);
+        return JWT.create()
+                .withIssuer(login)
+                .withIssuedAt(now)
+                .withExpiresAt(validity)
+                .sign(Algorithm.HMAC256(secretKey));
+    }
+
+    public Authentication validateToken(String token) {
+        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
+
+        DecodedJWT decoded = verifier.verify(token);
+
+        UserDto user = userService.findByEmail(decoded.getIssuer());
+
+        return new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList());
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/dto/CredentialsDto.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/dto/CredentialsDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/dto/CredentialsDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,15 @@
+package com.example.rezevirajmasa.demo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Data
+public class CredentialsDto {
+    private String login;
+    private char[] password;
+}
Index: src/main/java/com/example/rezevirajmasa/demo/dto/ErrorDto.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/dto/ErrorDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/dto/ErrorDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,12 @@
+package com.example.rezevirajmasa.demo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+@AllArgsConstructor
+@Builder
+@Data
+public class ErrorDto {
+    private String message;
+}
Index: src/main/java/com/example/rezevirajmasa/demo/dto/SignUpDto.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/dto/SignUpDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/dto/SignUpDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,17 @@
+package com.example.rezevirajmasa.demo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Data
+public class SignUpDto {
+    private String firstName;
+    private String lastName;
+    private String email;
+    private char[] password;
+}
Index: src/main/java/com/example/rezevirajmasa/demo/dto/UserDto.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/dto/UserDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/dto/UserDto.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,18 @@
+package com.example.rezevirajmasa.demo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Data
+public class UserDto {
+    private Long id;
+    private String firstName;
+    private String lastName;
+    private String email;
+    private String token;
+}
Index: src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapper.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapper.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapper.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,16 @@
+package com.example.rezevirajmasa.demo.mappers;
+
+
+import com.example.rezevirajmasa.demo.dto.SignUpDto;
+import com.example.rezevirajmasa.demo.dto.UserDto;
+import com.example.rezevirajmasa.demo.model.User;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+
+@Mapper(componentModel = "spring")
+public interface UserMapper {
+    UserDto toUserDto(User user);
+
+    @Mapping(target = "password", ignore = true)
+    User signUpToUser(SignUpDto userDto);
+}
Index: src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapperImpl.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapperImpl.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/mappers/UserMapperImpl.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,42 @@
+package com.example.rezevirajmasa.demo.mappers;
+
+import com.example.rezevirajmasa.demo.dto.SignUpDto;
+import com.example.rezevirajmasa.demo.dto.UserDto;
+import com.example.rezevirajmasa.demo.model.User;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+@Component
+public class UserMapperImpl implements UserMapper {
+
+    @Override
+    public UserDto toUserDto(User user) {
+        if (user == null) {
+            return null;
+        }
+
+        UserDto userDto = new UserDto();
+        userDto.setId(user.getId());
+        userDto.setFirstName(user.getFirstName());
+        userDto.setLastName(user.getLastName());
+        userDto.setEmail(user.getEmail());
+
+        return userDto;
+    }
+
+    @Override
+    public User signUpToUser(SignUpDto userDto) {
+        if (userDto == null) {
+            return null;
+        }
+
+        User user = new User();
+        user.setEmail(userDto.getEmail());
+        user.setFirstName(userDto.getFirstName());
+        user.setLastName(userDto.getLastName());
+        user.setPassword(Arrays.toString(userDto.getPassword()));
+
+        return user;
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/model/User.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/model/User.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/model/User.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,33 @@
+package com.example.rezevirajmasa.demo.model;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Data
+@Entity
+@Table(name = "app_user")
+public class User {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(name = "first_name")
+    private String firstName;
+
+    @Column(name = "last_name")
+    private String lastName;
+
+    @Column(nullable = false)
+    private String email;
+
+    @Column(nullable = false)
+    private String password;
+}
Index: src/main/java/com/example/rezevirajmasa/demo/model/exceptions/AppException.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/model/exceptions/AppException.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/model/exceptions/AppException.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,15 @@
+package com.example.rezevirajmasa.demo.model.exceptions;
+
+import org.springframework.http.HttpStatus;
+
+public class AppException extends RuntimeException{
+    private final HttpStatus code;
+    public AppException(String message, HttpStatus code) {
+        super(message);
+        this.code = code;
+    }
+
+    public HttpStatus getCode() {
+        return code;
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/model/exceptions/CustomerAuthenticationEntryPoint.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/model/exceptions/CustomerAuthenticationEntryPoint.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/model/exceptions/CustomerAuthenticationEntryPoint.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,26 @@
+package com.example.rezevirajmasa.demo.model.exceptions;
+
+import com.example.rezevirajmasa.demo.dto.ErrorDto;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+@Component
+public class CustomerAuthenticationEntryPoint implements AuthenticationEntryPoint {
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+    @Override
+    public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+        OBJECT_MAPPER.writeValue(response.getOutputStream(), new ErrorDto("Unauthorized path"));
+    }
+
+}
Index: src/main/java/com/example/rezevirajmasa/demo/repository/UserRepository.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/repository/UserRepository.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/repository/UserRepository.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,10 @@
+package com.example.rezevirajmasa.demo.repository;
+
+import com.example.rezevirajmasa.demo.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface UserRepository extends JpaRepository<User, Long> {
+    public Optional<User> findByEmail(String email);
+}
Index: src/main/java/com/example/rezevirajmasa/demo/service/UserService.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/service/UserService.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/service/UserService.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,13 @@
+package com.example.rezevirajmasa.demo.service;
+
+import com.example.rezevirajmasa.demo.dto.CredentialsDto;
+import com.example.rezevirajmasa.demo.dto.SignUpDto;
+import com.example.rezevirajmasa.demo.dto.UserDto;
+import lombok.RequiredArgsConstructor;
+
+
+public interface UserService {
+    public UserDto findByEmail(String email);
+    public UserDto login(CredentialsDto credentialsDto);
+    public UserDto register(SignUpDto userDto);
+}
Index: src/main/java/com/example/rezevirajmasa/demo/service/impl/UserServiceImpl.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/service/impl/UserServiceImpl.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/service/impl/UserServiceImpl.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,57 @@
+package com.example.rezevirajmasa.demo.service.impl;
+
+import com.example.rezevirajmasa.demo.dto.CredentialsDto;
+import com.example.rezevirajmasa.demo.dto.SignUpDto;
+import com.example.rezevirajmasa.demo.dto.UserDto;
+import com.example.rezevirajmasa.demo.mappers.UserMapper;
+import com.example.rezevirajmasa.demo.mappers.UserMapperImpl;
+import com.example.rezevirajmasa.demo.model.User;
+import com.example.rezevirajmasa.demo.model.exceptions.AppException;
+import com.example.rezevirajmasa.demo.repository.UserRepository;
+import com.example.rezevirajmasa.demo.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.mapstruct.control.MappingControl;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+import java.nio.CharBuffer;
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Service
+public class UserServiceImpl implements UserService {
+    private final UserRepository userRepository;
+    private final UserMapperImpl userMapper;
+    private final PasswordEncoder passwordEncoder;
+    @Override
+    public UserDto findByEmail(String email) {
+        User user = userRepository.findByEmail(email).orElseThrow(() -> new AppException(("Unknown user"), HttpStatus.NOT_FOUND));
+        return userMapper.toUserDto(user);
+    }
+
+    public UserDto login(CredentialsDto credentialsDto) {
+        User user = userRepository.findByEmail(credentialsDto.getLogin())
+                .orElseThrow(() -> new AppException("Unknown user", HttpStatus.NOT_FOUND));
+
+        if(passwordEncoder.matches(CharBuffer.wrap(credentialsDto.getPassword()), user.getPassword())) {
+            return userMapper.toUserDto(user);
+        }
+
+        throw new AppException("Invalid password", HttpStatus.BAD_REQUEST);
+    }
+
+    public UserDto register(SignUpDto userDto) {
+        Optional<User> optionalUser = userRepository.findByEmail(userDto.getEmail());
+        if(optionalUser.isPresent()) {
+            throw new AppException("Login already exists", HttpStatus.BAD_REQUEST);
+        }
+
+        User user = userMapper.signUpToUser(userDto);
+
+        user.setPassword(passwordEncoder.encode(CharBuffer.wrap(userDto.getPassword())));
+
+        User savedUser = userRepository.save(user);
+
+        return userMapper.toUserDto(user);
+    }
+}
Index: c/main/java/com/example/rezevirajmasa/demo/web/filters/AuthFilter.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/web/filters/AuthFilter.java	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package com.example.rezevirajmasa.demo.web.filters;
-
-import jakarta.servlet.*;
-import jakarta.servlet.annotation.WebFilter;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.context.annotation.Profile;
-
-import java.io.IOException;
-import java.util.logging.Filter;
-import java.util.logging.LogRecord;
-
-@Profile("servlet")
-@WebFilter(urlPatterns = "/*")
-public class AuthFilter implements Filter {
-    @Override
-    public boolean isLoggable(LogRecord record) {
-        return false;
-    }
-}
-
Index: src/main/java/com/example/rezevirajmasa/demo/web/filters/JwtAuthFilter.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/web/filters/JwtAuthFilter.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
+++ src/main/java/com/example/rezevirajmasa/demo/web/filters/JwtAuthFilter.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -0,0 +1,42 @@
+package com.example.rezevirajmasa.demo.web.filters;
+
+import com.example.rezevirajmasa.demo.config.UserAuthProvider;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpHeaders;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+
+@RequiredArgsConstructor
+public class JwtAuthFilter extends OncePerRequestFilter {
+
+    private final UserAuthProvider userAuthProvider;
+    @Override
+    protected void doFilterInternal(
+            HttpServletRequest request,
+            HttpServletResponse response,
+            FilterChain filterChain) throws ServletException, IOException {
+        String header = request.getHeader(HttpHeaders.AUTHORIZATION);
+
+        if(header != null) {
+            String[] elements = header.split(" ");
+
+            if(elements.length == 2 && "Bearer".equals(elements[0])) {
+                try {
+                    SecurityContextHolder.getContext().setAuthentication(
+                            userAuthProvider.validateToken(elements[1])
+                    );
+                } catch (RuntimeException e) {
+                    SecurityContextHolder.clearContext();
+                    throw e;
+                }
+            }
+        }
+        filterChain.doFilter(request, response);
+    }
+}
Index: src/main/java/com/example/rezevirajmasa/demo/web/rest/AuthController.java
===================================================================
--- src/main/java/com/example/rezevirajmasa/demo/web/rest/AuthController.java	(revision a2c6c2b23c1991c83def7a1876e03123c530e644)
+++ src/main/java/com/example/rezevirajmasa/demo/web/rest/AuthController.java	(revision 5a9c93b9db42777251b6230e5814b5929eb94488)
@@ -1,6 +1,12 @@
 package com.example.rezevirajmasa.demo.web.rest;
 
+import com.example.rezevirajmasa.demo.config.UserAuthProvider;
+import com.example.rezevirajmasa.demo.dto.CredentialsDto;
+import com.example.rezevirajmasa.demo.dto.SignUpDto;
+import com.example.rezevirajmasa.demo.dto.UserDto;
 import com.example.rezevirajmasa.demo.model.Customer;
 import com.example.rezevirajmasa.demo.service.CustomerService;
+import com.example.rezevirajmasa.demo.service.UserService;
+import lombok.RequiredArgsConstructor;
 import org.apache.coyote.Response;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -14,30 +20,24 @@
 import org.springframework.web.bind.annotation.RestController;
 
-@CrossOrigin(origins = "http://localhost:3000/")
+import java.net.URI;
+
+@RequiredArgsConstructor
 @RestController
 public class AuthController {
-    private final CustomerService customerService;
-    private final PasswordEncoder passwordEncoder;
-
-    public AuthController(CustomerService customerService, PasswordEncoder passwordEncoder) {
-        this.customerService = customerService;
-        this.passwordEncoder = passwordEncoder;
+    private final UserService userService;
+    private final UserAuthProvider userAuthProvider;
+    @PostMapping("/api/login")
+    public ResponseEntity<UserDto> login(@RequestBody CredentialsDto credentialsDto) {
+        UserDto user = userService.login(credentialsDto);
+        user.setToken(userAuthProvider.createToken(user.getEmail()));
+        return ResponseEntity.ok(user);
     }
 
-    @PostMapping("/api/login")
-    public ResponseEntity<String> login(@RequestBody Customer customer) {
-        Customer exisitngCustomer = customerService.findByEmail(customer.getEmail());
-
-        if(passwordEncoder.matches(customer.getPassword(), exisitngCustomer.getPassword())) {
-            String token = generateToken(exisitngCustomer);
-            return ResponseEntity.ok(token);
-        } else {
-            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
-        }
-    }
-
-    private String generateToken(Customer customer) {
-        // Implement your token generation logic here
-        return "dummy_token";
+    @PostMapping("/api/register")
+    public ResponseEntity<UserDto> register(@RequestBody SignUpDto signUpDto) {
+        UserDto user = userService.register(signUpDto);
+        user.setToken(userAuthProvider.createToken(user.getEmail()));
+        return ResponseEntity.created(URI.create("/users/" + user.getId()))
+                .body(user);
     }
 }
