(Udacity) Lesson 5: Data Persistence & Security

36583 단어 udacityudacity

1. 영구적인 데이터 저장을 위한 ORM(Object Relational Mapping)의 장점을 고르시오

1) JDBC보다 빠르다
2) 우리가 우리 객체의 모든 필드를 참조하는 쿼리를 쓰는 것을 막는다.
3) 자바 객체로써 영구적인 데이터를 쉽게 작업할 수 있게 한다.

4) 한번에 여러개의 쿼리를 작업할 수 있게 한다. -> 모든 데이터베이스의 장점

2. 다음 중 사용자가 로그인해야 볼 수 있는 웹 페이지 부분은 무엇입니까?

1) 상품 카탈로그
2) 모든 인벤토리
3) 특정 고객 쇼핑카트

4) 모든 고객 쇼핑카트
5) 회사 연락 정보

3. 일부 데이터는 데이터베이스에 속하지만, 모든 데이터를 데이터베이스에 넣으려고 하면 느려진다. 온라인 쇼핑몰 사이트를 만들때 데이터베이스에 넣어야 할 것은?

1) 사용자 프로필
2) 제품 리스트

3) 상품 검색 결과
4) 쇼핑카트
5) 상품 이미지

-> 보통 사진은 안넣는다.

4. 자바 변수들중에 상응하는 컬럼을 고르시오

1) String username; - VARCHAR
2) Integer numberOfCats - INTEGER
3) LocalDate birthDate - DATE
4) Double priceOfSalmon - DECIMAL
5) Boolean passedTheQuiz - BOOL

5. 클래스 작성

  1. Customer.java
public class Customer {
   private Integer id;
   private String userName;
   private String password;

   /* getters and setters not shown */
}
  1. Order.java
public class Order {
   private Integer id;
   private Integer customerId;

   /* getters and setters not shown */
}
  1. TacoOrder.java
public class TacoOrder {
   private Integer orderId;
   private String tacoName;
   // this will work here, but you should often use BigDouble for prices 
   // if you plan to do any math with them
   private Double tacoPrice;
   private Integer count;

  /* getters and setters not shown */
}
public class Delivery {
   private Integer id;
   private Integer orderId;
  // there are a few types you can use for this. 
  // java.sql.Timestamp contains both date and time
   private Timestamp time;

   /* getters and setters not shown */
}

6. MyBatis에 대해 옳은것은?

1) MyBatis는 interface만으로 bean을 생성한다.
2) 데이터 베이스에 새로운 사용자를 추가하기 위해 @Select annotation을 사용해야 한다.
3) MyBatis 쿼리의 변수는 메소드 매개 변수의 객체 또는 객체의 속성을 참조할 수 있다.
4) @Insert annotation은 새롭게 생성된 row id를 반환한다.

7. 기존의 데이터베이스에 새롭게 추가하고싶다. 어떤 예제를 삽입해야 하는가?

public class TacoOrder {
   private Integer orderId;
   private String tacoName;
   private Double tacoPrice;
   private Integer count;
   /* getters and setters not shown */
}

답:

@Insert(
  "INSERT INTO TacoOrder (orderId, tacoName, tacoPrice, count)"
  + " VALUES (#{orderId}, #{tacoName}, #{tacoPrice}, #{count})"
)
int addToOrder(TacoOrder tacoOrder);

8. @Mapper interface를 생성하라

public class Delivery {
   private Integer id;
   private Integer orderId;
   private Timestamp time;
   /* getters and setters not shown */
}

The findDelivery (or select) method should take the id of our Delivery class and return the corresponding Delivery object.
The insert method should take a Delivery object and create a new record with the orderId and time. It should generate a new id and return that id.
The delete method should take an id and delete that record from the database. It doesn’t need to return anything

답:

@Mapper
public interface DeliveryMapper {
    
    @Select("SELECT * FROM Delivery WHERE id = #{id}")
    Delivery findDelivery(Integer id);
    
    @Insert("INSERT INTO Delivery (orderId, time) VALUES(#{orderId}, #{time}")
    @Option(useGenerateKeys = true, keyProperty = "id")
    Integer insert(Delivery delivery);
    
    @Delete("DELETE FROM Delivery WHERE id = #{id}")
    void delete(Integer id);

암호화 데모1

User.java

public class User {
	private Integer userId;
	private String username;
	private String salt;
	private String password;
	private String firstName;
	private String lastName;
	/* constructor, getters, and setters omitted */
}

UserMapper.java

@Mapper
public interface UserMapper
	@Select("SELECT * FROM USERS WHERE username = #{username}")
	User getUser(String username);
	@Insert("INSERT INTO USERS (username, salt, password, firstname, lastname) 
VALUES(#{username}, #{salte}, #{password}, #{firstname}, #{lastname})")
	@Options(useGeneratedKeys = true, keyProperty = "userId")
int insert(User user);

Method in UserService.java

public int creatUser(User user) {
	SecureRandom random = new SecureRandom();
	byte[] salt = new byte[16];
	random.nextBytes(salt);
	String encodedSalt = Base64.getEncoder().encodeToString(salt);
	String hashedPassword = hashService.getHashedValue(user.getPassword(), encodedSalt);
	return userMapper.insert(new User(null, user.getUsername(), encodedSalt, hashedPassword,
user.getFirstNanme(), user.getLastNAme()));
}

Method in HashService.java

public String getHashedValue(String data, String salt) {
	byte[] hashedValue = null;
	KeySpec spec = new PBEKeySpec(data.toCharArray(). salt.getBytes(), 5000, 128);
	try {
		SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
		hashedValue = factory.generateSecret(spec).getEncoded();
	} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
		logger.error(e.getMessage());
	}
	return Base64.getEncoder().encodeToString(hashedValue);
}

AuthenticationService.java

@Service
public class AuthenticationService implements AuthenticationProvider {
    private UserMapper userMapper;
    private HashService hashService;
    public AuthenticationService(UserMapper userMapper, HashService hashService) {
        this.userMapper = userMapper;
        this.hashService = hashService;
    }
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();
        User user = userMapper.getUser(username);
        if (user != null) {
            String encodedSalt = user.getSalt();
            String hashedPassword = hashService.getHashedValue(password, encodedSalt);
            if (user.getPassword().equals(hashedPassword)) {
                return new UsernamePasswordAuthenticationToken(username, password, new ArrayList<>());
            }
        }
        return null;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

암호화 데모2

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private AuthenticationService authenticationService;
    public SecurityConfig(AuthenticationService authenticationService) {
        this.authenticationService = authenticationService;
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(this.authenticationService);
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/signup", "/css/**", "/js/**").permitAll()
                .anyRequest().authenticated();
        http.formLogin()
                .loginPage("/login")
                .permitAll();
        http.formLogin()
                .defaultSuccessUrl("/home", true);
    }
}

9. 알맞는것 매칭

1) Filter -
2) FilterRegistrationBean -
3) AuthenticationProvider -
4) AuthenticationService -
5) HashService -
6) SecurityConfig -
7) WebSecurityConfigAdapter -

Object used to association filters with URL patterns
Interface describing methods for checking user credentials
Implents the methods for checking user credentials
Implements the methods that modify Spring's configuration to use our Services
Implements the methods for encrypting our secret data
Interface describing methods for taking action when an HttpRequest is received
Interface describing the methods that modify Spring's security configuration

10. SecurityConfig.java 수정해보기

configure method

@Override
protected void configure(HttpSecurity http) throws Exception {
   http.authorizeRequests()
           .antMatchers("/order", "/css/**", "/js/**").permitAll()
           .anyRequest().authenticated();
   http.formLogin()
           .loginPage("/login")
           .permitAll();
   http.formLogin()
           .defaultSuccessUrl("/tacos", true);
}

첫 번째 메서드 체인은 /order 페이지, css , js 디렉토리에 대한 모든 요청을 허용하고 인증된 사용자가 어떤 종류의 요청도 할 수 있게 한다.
다음 체인은 모든 사용자가 /로그인의 자동 생성 로그인 페이지에 액세스할 수 있도록 허용한다.
마지막으로 세 번째 메소드 체인은 기본적으로 성공적인 로그인을 /tacos 페이지로 리다이렉션 한다.

좋은 웹페이지 즐겨찾기