JWT tokens
This commit is contained in:
parent
3179d75ff7
commit
ded05785dc
|
@ -94,6 +94,17 @@
|
|||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package ch.bbw.pr.tresorbackend.controller;
|
||||
|
||||
import ch.bbw.pr.tresorbackend.model.AuthRequest;
|
||||
import ch.bbw.pr.tresorbackend.model.AuthResponse;
|
||||
import ch.bbw.pr.tresorbackend.model.User;
|
||||
import ch.bbw.pr.tresorbackend.repository.UserRepository;
|
||||
import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService;
|
||||
import ch.bbw.pr.tresorbackend.util.JwtUtil;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/api/auth")
|
||||
public class AuthController {
|
||||
private JwtUtil jwtUtil;
|
||||
private UserRepository userRepository;
|
||||
private PasswordEncryptionService passwordService;
|
||||
|
||||
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
||||
@PostMapping("/")
|
||||
public ResponseEntity<?> authentication(@Valid @RequestBody AuthRequest request) {
|
||||
User user = userRepository.findByEmail(request.getEmail()).orElse(null);
|
||||
if (user == null || !passwordService.verifyPassword(user, request.getPassword()) ) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
String token = jwtUtil.generateToken(user);
|
||||
return ResponseEntity.ok(new AuthResponse(token));
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import ch.bbw.pr.tresorbackend.model.*;
|
|||
import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService;
|
||||
import ch.bbw.pr.tresorbackend.service.UserService;
|
||||
|
||||
import ch.bbw.pr.tresorbackend.util.Role;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -22,6 +23,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
/**
|
||||
* UserController
|
||||
*
|
||||
* @author Peter Rutschmann
|
||||
*/
|
||||
@RestController
|
||||
|
@ -85,7 +87,8 @@ public class UserController {
|
|||
registerUser.getLastName(),
|
||||
registerUser.getEmail(),
|
||||
passwordService.hashPassword(registerUser.getPassword()),
|
||||
null
|
||||
null,
|
||||
Role.USER
|
||||
);
|
||||
|
||||
User savedUser = userService.createUser(user);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package ch.bbw.pr.tresorbackend.model;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class AuthRequest {
|
||||
String email;
|
||||
String password;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package ch.bbw.pr.tresorbackend.model;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class AuthResponse {
|
||||
String token;
|
||||
public AuthResponse(String token) { this.token = token; }
|
||||
public String getToken() { return token; }
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package ch.bbw.pr.tresorbackend.model;
|
||||
|
||||
import ch.bbw.pr.tresorbackend.util.Role;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
@ -35,4 +36,8 @@ public class User {
|
|||
|
||||
@Column(nullable = true)
|
||||
private String two_fa_secret;
|
||||
|
||||
@Column(nullable = true)
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Role role;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package ch.bbw.pr.tresorbackend.util;
|
||||
|
||||
import ch.bbw.pr.tresorbackend.model.User;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class JwtUtil {
|
||||
private final String SECRET = "secret-key";
|
||||
|
||||
public String generateToken(User user) {
|
||||
return Jwts.builder()
|
||||
.setSubject(user.getEmail())
|
||||
.claim("role", user.getRole().name())
|
||||
.setIssuedAt(new Date())
|
||||
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
|
||||
.signWith(SignatureAlgorithm.HS256, SECRET.getBytes())
|
||||
.compact();
|
||||
}
|
||||
|
||||
public Claims validateToken(String token) throws ExpiredJwtException {
|
||||
return Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(token).getBody();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package ch.bbw.pr.tresorbackend.util;
|
||||
|
||||
public enum Role {
|
||||
USER, ADMIN
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
export const fetchJwtToken = async (loginValues) => {
|
||||
const protocol = process.env.REACT_APP_API_PROTOCOL; // "http"
|
||||
const host = process.env.REACT_APP_API_HOST; // "localhost"
|
||||
const port = process.env.REACT_APP_API_PORT; // "8080"
|
||||
const path = process.env.REACT_APP_API_PATH; // "/api"
|
||||
const portPart = port ? `:${port}` : ''; // port is optional
|
||||
const API_URL = `${protocol}://${host}${portPart}${path}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/auth/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: loginValues.email,
|
||||
password: loginValues.password,
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const resJson = await response.json();
|
||||
console.log(resJson)
|
||||
console.log(resJson.token)
|
||||
return resJson.token
|
||||
}
|
||||
throw new Error('jwttoken is not okey');
|
||||
} catch (error) {
|
||||
console.error('Failed to get jwt', error.message);
|
||||
throw new Error('Failed to get jwt' || error.message);
|
||||
}
|
||||
};
|
|
@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom';
|
|||
import { loginUser, captchaCheck } from '../../comunication/FetchUser';
|
||||
import ReCAPTCHA from 'react-google-recaptcha';
|
||||
import { generate2FACode, verify2FACode } from '../../comunication/TwoFactorAuth';
|
||||
import { fetchJwtToken } from '../../comunication/JwtToken';
|
||||
|
||||
/**
|
||||
* LoginUser
|
||||
|
@ -45,6 +46,8 @@ function LoginUser({ loginValues, setLoginValues }) {
|
|||
const verify2FA = async () => {
|
||||
const res = await verify2FACode({ loginValues, code });
|
||||
if (res) {
|
||||
const jwtToken = await fetchJwtToken(loginValues)
|
||||
document.cookie = "jwtToken=" + jwtToken;
|
||||
navigate('/')
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue