(Udacity) Lesson 5: Data Persistence & Security


1.データを永続的に保存するためのオブジェクト関係マッピング(ORM)の選択の利点


1)JDBCより速い
2)オブジェクトのすべてのフィールドを参照するクエリーの作成をブロックします.
3)Javaオブジェクトを使用すると,永続的なデータを簡単に処理できる.
4)複数のクエリーを一度に操作できるようにします.->すべてのデータベースのメリット

2.表示するには、ユーザーがログインする必要があるWebページのセクションはどれですか?


1)カタログ
2)全在庫
3)特定顧客カート
4)すべての顧客のショッピングカート
5)会社連絡情報

3.一部のデータはデータベースに属しますが、すべてのデータをデータベースに入れるのは遅くなります。ネットショッピングサイトを作成するときにデータベースに入れるべきものは?


1)ユーザープロファイル
2)製品リスト
3)商品検索結果
4)ショッピングカート
5)商品イメージ
写真を置かないのが普通です.

4.Java変数で該当する列を選択


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

5.クラスの作成


  • Customer.java
  • public class Customer {
       private Integer id;
       private String userName;
       private String password;
    
       /* getters and setters not shown */
    }
  • Order.java
  • public class Order {
       private Integer id;
       private Integer customerId;
    
       /* getters and setters not shown */
    }
  • 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)MyBasisはインタフェースのみでbeanを生成する.
    2)@Selectコメントを使用して、新しいユーザーをデータベースに追加する必要があります.
    3)MyBatisクエリの変数はメソッドパラメータのオブジェクトまたはオブジェクトの属性を参照できます.
    4)@Insertコメントは、新しく生成された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インタフェースの作成

    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ディレクトリのすべてのリクエストを許可し、認証されたユーザーに任意のタイプのリクエストを許可します.
    次のリンクを使用すると、すべてのユーザーがログイン・ページにアクセス/ログインできるようになります.
    最後に、3番目のメソッドチェーンでは、基本的に成功したログインが/tacosページにリダイレクトされます.