Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

부산대 BE_이풍헌 2주차 과제(step2) #298

Open
wants to merge 12 commits into
base: canyos
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ repositories {
}

dependencies {

implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'org.springframework.security:spring-security-crypto:5.7.1'
implementation 'org.thymeleaf:thymeleaf:3.1.2.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-validation:2.7.0'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/gift/Util/CommonConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package gift.Util;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class CommonConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
77 changes: 77 additions & 0 deletions src/main/java/gift/Util/JWTUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package gift.Util;

import gift.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;


import javax.crypto.SecretKey;
import java.util.Date;

public class JWTUtil {

private static final SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
/**
* 토큰 생성
*/
public static String generateToken(User user) {
Claims claims = Jwts.claims();
claims.put("username", user.getUserId());
return createToken(claims, user.getUserId());
}

private static String createToken(Claims claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
.signWith(SignatureAlgorithm.HS256, key)
.compact();
}

/**
* 토큰 유효여부 확인
*/
public Boolean isValidToken(String token, User user) {
//log.info("isValidToken token = {}", token);
String username = getUsernameFromToken(token);
return (username.equals(user.getUserId()) && !isTokenExpired(token));
}

/**
* 토큰의 Claim 디코딩
*/
private Claims getAllClaims(String token) {
//log.info("getAllClaims token = {}", token);
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token)
.getBody();
}

/**
* Claim 에서 username 가져오기
*/
public String getUsernameFromToken(String token) {
String username = String.valueOf(getAllClaims(token).get("username"));
//log.info("getUsernameFormToken subject = {}", username);
return username;
}

/**
* 토큰 만료기한 가져오기
*/
public Date getExpirationDate(String token) {
Claims claims = getAllClaims(token);
return claims.getExpiration();
}

/**
* 토큰이 만료되었는지
*/
private boolean isTokenExpired(String token) {
return getExpirationDate(token).before(new Date());
}
}
32 changes: 23 additions & 9 deletions src/main/java/gift/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
package gift.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import gift.entity.Token;

import gift.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

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


@Controller
public class UserController {
@Autowired
UserService userService;

@GetMapping("/user/signup")
@Autowired
ObjectMapper objectMapper;

@GetMapping("/signup")
public String signUp() {
return "user/signup";
}

@PostMapping("/api/signup")
public String SignUp(@RequestParam("user_id") String user_id, @RequestParam("password") String password) {
userService.signUp(user_id,password);
return "redirect:/user/signin";

public String SignUp(@RequestParam("email") String email, @RequestParam("password") String password) {
userService.signUp(email,password);
return "redirect:/signin";
}

@GetMapping("/user/signin")
@GetMapping("/signin")
public String signIn() {
return "user/signin";
}

// @PostMapping("/api/signup")
// public void signIn(@RequestParam("user_id") String user_id, @RequestParam("password") String password) {
// userService.signIn(user_id,password);
// }
@PostMapping("/api/signin")
@ResponseBody
public String signIn(@RequestParam("email") String email, @RequestParam("password") String password) throws JsonProcessingException {
Token token = userService.signIn(email,password);
return objectMapper.writeValueAsString(token);
}

}
13 changes: 13 additions & 0 deletions src/main/java/gift/entity/Token.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package gift.entity;

public class Token {
String token;

public Token(String token) {
this.token = token;
}

public String getToken() {
return token;
}
}
10 changes: 6 additions & 4 deletions src/main/java/gift/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

public class User {
private static int id = 1;
private String userId;

private String email;

private String userPw;

public int getId() {
return id;
}

public String getUserId() {
return userId;
return email;
}

public String getUserPw() {
return userPw;
}

public User(String userId, String userPw) {
public User(String email, String userPw) {
this.id = id++;
this.userId = userId;
this.email = email;
this.userPw = userPw;
}
}
30 changes: 25 additions & 5 deletions src/main/java/gift/repository/UserRepository.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
package gift.repository;

import gift.entity.Product;
import gift.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;

import java.util.List;


@Repository
public class UserRepository {
@Autowired
JdbcTemplate jdbcTemplate;

public boolean isExistAccount(String userId) {
String sql = "select count(*) from user_tb where user_id=?";
int count = jdbcTemplate.queryForObject(sql, Integer.class, userId);
@Autowired
PasswordEncoder passwordEncoder;

public boolean isExistAccount(String email) {
String sql = "select count(*) from user_tb where email=?";
int count = jdbcTemplate.queryForObject(sql, Integer.class, email);
return count > 0;
}

public void saveUser(User user) {
String sql = "insert into user_tb(id, user_id, user_pw) values(?,?,?)";
jdbcTemplate.update(sql,user.getId(),user.getUserId(),user.getUserPw());
String sql = "insert into user_tb(id, email, password) values(?,?,?)";
String hashPw = passwordEncoder.encode(user.getUserPw());
jdbcTemplate.update(sql,user.getId(),user.getUserId(),hashPw);
}

public User findUserbyID(String email){
String sql= "select * from user_tb where email=?";
List<User> user = jdbcTemplate.query(sql,new Object[]{email},(rs, rowNum) -> new User(
rs.getString("email"),
rs.getString("password")
));
return user.getFirst();
}
}
25 changes: 21 additions & 4 deletions src/main/java/gift/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
package gift.service;

import gift.Util.JWTUtil;
import gift.entity.Token;
import gift.entity.User;
import gift.exception.*;
import gift.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class UserService {
@Autowired
UserRepository userRepository;
@Autowired
PasswordEncoder passwordEncoder;

public void signUp(String email, String password) {
if(userRepository.isExistAccount(email))
throw new Exception400("이미 존재하는 계정");
userRepository.saveUser(new User(email, password));
}

public Token signIn(String email, String password){
User user = userRepository.findUserbyID(email);
if(!userRepository.isExistAccount(email))
throw new Exception404("존재하지 않는 계정");
if (!passwordEncoder.matches(password, user.getUserPw()))
throw new Exception400("비밀번호가 일치하지 않습니다.");

public void signUp(String userId, String password) {
if(userRepository.isExistAccount(userId))
throw new Exception404("이미 존재하는 계정");
userRepository.saveUser(new User(userId, password));
return new Token(JWTUtil.generateToken(user));
}
}
3 changes: 0 additions & 3 deletions src/main/resources/db/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,3 @@ insert into option(id,option) values(1,'1');

insert into product(id, name , price , imageUrl) values(2,'2',2,'2');
insert into option(id,option) values(2,'2');

insert into user_tb(id,user_id,user_pw) values(1,'asdf','asdf');
insert into user_tb(id,user_id,user_pw) values(2,'qwer','qwer');
3 changes: 2 additions & 1 deletion src/main/resources/db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ CREATE TABLE product(id SERIAL, name VARCHAR(255), price int, imageUrl varchar(2
DROP TABLE option IF exists;
CREATE TABLE option (id int, option varchar(255));
DROP TABLE user_tb IF exists;
CREATE TABLE user_tb(id SERIAL, user_id varchar(20), user_pw varchar(20));
CREATE TABLE user_tb(id SERIAL, email varchar(255), password varchar(255));

5 changes: 3 additions & 2 deletions src/main/resources/templates/user/signin.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
<!-- Form to add a new product (POST request) -->
<h2>Sign In</h2>
<form th:action="@{/api/signin}" method="post">
<label for="user_id">UserID:</label>
<input type="text" id="user_id" name="user_id" required>
<label for="email">UserID:</label>
<input type="text" id="email" name="email" required>

<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/user/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<!-- Form to add a new product (POST request) -->
<h2>Sign Up</h2>
<form th:action="@{/api/signup}" method="post">
<label for="user_id">UserID:</label>
<input type="text" id="user_id" name="user_id" required>
<label for="email">UserID:</label>
<input type="text" id="email" name="email" required>
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
Expand Down