Spring Spring Security+JWTログイン-1の実装(ドメインの設定、作成、レポートの作成)



私はMySQLではなくPostgreSQLを使っています.
ダウンロード後使用build.gradleオープンアイテム
いくつかのdependencyを追加します.
	//jwt
	implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
	implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
	implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2'
    
    //<!-- For Java 8 Date/Time Support -->
	// https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jsr310
	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

サーバ、データベース、Hibernate、Jackson設定

server:
  port: 8080
  servlet:
    context-path: /
    encoding:
      charset: utf-8
      enabled: true

spring:
  profiles:
    include: aws
  output.ansi.enabled: always
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: update # create, update, none
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    #show-sql: true
    format-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        default_schema: 스키마 이름
    defer-datasource-initialization: true

# DB설정은 본인 DB설정 찾아서 yml 파일에 해주면 된다.

  jackson:
    serialization:
      write-dates-as-timestamps: false
    time-zome: Asia/Seoul

app:
  jwtSecret: jwtsigntutorialasdfasdfasdfasdfasdf
  jwtExpirationInMs: 604800000

logging.level:
  org.hibernate.SQL: debug
  org.hibernate.type: trace
JacksonのWRITE DATE AS TIMESTAMPSプロパティは、Java 8のデータ/時間値をタイムスタンプにシリアル化することを無効にします.すべての日付/時刻値はISO日付/時刻文字列でシリアル化されています.

Spring Bootを設定してJava 8の日付/時間を設定


ドメインモデルではJava 8データ/時間クラスが使用されます.JPA 2.1変換器を登録すると、ドメインモデルのすべてのJava 8日付/時刻フィールドがデータベースに保存されているときに自動的にSQLタイプに変換されます.

@EnableJpaAuditing
@SpringBootApplication
@EntityScan(basePackageClasses = {
	BackendApplication.class,
	Jsr310JpaConverters.class
})
public class BackendApplication {

	@PostConstruct
	void init() {
		TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
	}

	public static void main(String[] args) {
		SpringApplication.run(BackendApplication.class, args);
	}
}

ドメインモデルの作成


各ユーザーには1つ以上のロールがあります.ユーザーに関連するロールは、将来のユーザーがサーバ上の特定のリソースにアクセスできるかどうかを決定するために使用されます.
このセクションでは、ユーザーとRol eドメインモデルを作成します.モデルというパッケージを作成してください~
1.ユーザーモデル
ユーザー・モデルには、次のフィールドがあります.
  • id:キー
  • username:一意ユーザ名
  • email:ユニークなメール
  • password:暗号化された形式で格納されるパスワード.
  • roles:キャラクター集合.Role(エンティティとの複数対多の関係)->複数対多はよくない...とりあえず、ダダ任
  • User.java
    
    @Entity @Getter @Setter
    @Table(name = "users")
    public class User extends BaseEntity {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @NotBlank
        @Size(max = 40)
        private String name;
    
        @NotBlank
        @Size(max = 15)
        private String username;
    
        @NaturalId
        @NotBlank
        @Size(max = 40)
        @Email
        private String email;
    
        @NotBlank
        @Size(max = 100)
        private String password;
    
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name = "user_roles",
                joinColumns = @JoinColumn(name = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "role_id"))
        private Set<Role> roles = new HashSet<>();
    
        public User() {
    
        }
    
        public User(String name, String username, String email, String password) {
            this.name = name;
            this.username = username;
            this.email = email;
            this.password = password;
        }
    }
    
    ちなみに、@NotBlank@Sizeなどの制限事項は、ドメインではなくDTOで検証することが望ましい.
    2.ロールモデル
    Roleクラスには、フィールドidが含まれています.フィールドはnameです.定義済みの固定キャラクタセットが存在します.したがって、ロール名をに作成することをお勧めします.
    Role.java
    
    @Entity @Getter @Setter
    @Table(name = "roles")
    public class Role {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Enumerated(EnumType.STRING)
        @NaturalId
        @Column(length = 60)
        private RoleName name;
    
        public Role() {
    
        }
    
        public Role(RoleName name) {
            this.name = name;
        }
    }
    RoleName enumの作成
    public enum  RoleName {
        ROLE_USER,
        ROLE_ADMIN
    }
    3.BaseEntityの作成
    新しいauditというパッケージを作成し、そこに~を作成してください.
    createdAtフィールドとupdatedAtフィールドがあるはずです.これらの監査フィールドが必要なドメインモデルは、クラスを展開するだけです.
    @EqualsAndHashCode
    @MappedSuperclass
    @Getter
    @EntityListeners(AuditingEntityListener.class)
    @JsonIgnoreProperties(
    	value = {"createdAt", "updatedAt"},
    	allowGetters = true
    )
    public abstract class BaseEntity {
    
    	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    	protected Long id;
    
    	@CreatedDate
    	@Column(nullable = false)
    	private LocalDateTime createdAt;
    
    	@LastModifiedDate
    	private LocalDateTime updatedAt;
    }

    ユーザー、ロールリポジトリの作成


    JPAを使用してDebeにレポートを作成し、メンテナンスと取得を行います.repositoryというパッケージを作成し、その中に記入してください.
    1. UserRepository.java
    import com.example.polls.model.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    import java.util.List;
    import java.util.Optional;
    
    public interface UserRepository extends JpaRepository<User, Long> {
        Optional<User> findByEmail(String email);
    
        Optional<User> findByUsernameOrEmail(String username, String email);
    
        List<User> findByIdIn(List<Long> userIds);
    
        Optional<User> findByUsername(String username);
    
        Boolean existsByUsername(String username);
    
        Boolean existsByEmail(String email);
    }
    2. RoleRepository.java
    import com.example.polls.model.Role;
    import com.example.polls.model.RoleName;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    import java.util.Optional;
    
    @Repository
    public interface RoleRepository extends JpaRepository<Role, Long> {
        Optional<Role> findByName(RoleName roleName);
    }

    データベースのデフォルトロールの作成


    アプリケーションには、定義済みの固定ロールセットがあります.デフォルトでは、ユーザーがログインするたびにROLE USERが割り当てられます.
    ロールを割り当てるには、データベース内でなければなりません.そこで、次の挿入文を実行して、データベースに2つのデフォルトロールを作成します.
    INSERT INTO roles(name) VALUES('ROLE_USER');
    INSERT INTO roles(name) VALUES('ROLE_ADMIN');
    次編では、Spring Securityの構成、新規ユーザーの登録、ログイン機能を追加します.