SpringSecurityでログイン機能の導入手順を解説しています

SpringBoot

はじめに

こちらの記事をご覧になられると、ログイン機能を実装する際の概要や、準備手順を知る事ができます。

準備手順とは…

  • build.gradle編集(依存関係を追加する)
  • Entity作成
  • Repository作成

テーブル設計に倣ってテーブルを作成する事から始まりテストデータを挿入するところまでをゴールとしています。

また、こちらの記事は学習時間管理アプリ作成の続きの記事となりますため、良く分からない場合過去の記事を参照頂けると幸いです。

要件を整理する

機能要件

  • ユーザーは新規登録する事で本アプリにログイン出来る
  • ログイン後は学習時間管理画面へ遷移する
  • ログアウトをする事が出来る
  • 管理者機能の実装は行わない

スキーマ

ER図
  • リレーション

1人のユーザーは複数の学習時間をデータでもつ、従って「1対多」の関係である。

1人のユーザーは複数の役割(権限)を持つことが出来る、従って「多対1」の関係である。

※本アプリでは、一人のユーザーは複数の役割を持てるように設計します。但し、管理者は実装しないので実質上「1対1」です。後の保守を考えると上記の設計の方がよいと判断しました。

テーブル設計

usersテーブル

rolesテーブル

study_timesテーブル

SpringSecurityでログイン機能を実装

まずは、テーブル設計に倣って、DDLを作成し、テーブルを作成してください。

SQL
-- DDL
CREATE TABLE users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    user_name VARCHAR(50) NOT NULL,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    enabled TINYINT(1) NOT NULL,
    role_id INT NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);

CREATE TABLE roles (
    role_id INT AUTO_INCREMENT PRIMARY KEY,
    role_name VARCHAR(50) NOT NULL
);

build.gradle編集・Entity・Repository作成

build.gradle編集する

「build.gradle」を編集します。以下のコードを追加して、springセキュリティをプロジェクト使用できるようにします。追加する際は「dependencies」の部分に追加しましょう。

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
testImplementation 'org.springframework.security:spring-security-test'

編集後は以下のような形になればOKです!

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.3.4'
	id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.mysql:mysql-connector-j'
	annotationProcessor 'org.projectlombok:lombok'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
	useJUnitPlatform()
}

Entityを作成する

今までの流れでパッケージは作成されているはずです。こちらの下に追加していきましょう。ファイル形式は「クラス」です。

Role.javaを作成する

権限管理用のエンティティを作成します。

Role.java
package com.app.progTrack.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "roles")
@Data
public class Role {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "role_id")
	private Integer roleId;
	
	@Column(name = "role_name", length = 50, nullable = false, unique = true)
	private String roleName;
}
User.javaを作成する

ユーザー用のエンティティを作成します。

User.java
package com.app.progTrack.entity;

import java.sql.Timestamp;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Data;

@Entity
@Table(name = "users")
@Data
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "user_id")
	private Integer userId;
	
	@Column(name = "user_name")
	private String userName;
	
	@Column(name = "email")
	private String email;
	
	@Column(name = "password")
	private String password;
	
	@Column(name = "enabled")
	private Boolean enabled;
	
	@ManyToOne
	@JoinColumn(name = "role_id")
	private Role role;
	
	@Column(name = "created_at", insertable = false, updatable = false)
	private Timestamp createdAt;
	
	@Column(name = "updated_at", insertable = false, updatable = false)
	private Timestamp updatedAt;

}

Repositoryを作成する

既存で作成してある「repository」パッケージの下に「RoleRepository.java」を作成します。インターフェースなので間違えないようにしてくださいね!

RoleRepository.javaを作成する

権限管理用のリポジトリを作成します。Jpaを継承して引数を渡せばOKです!

基本的な書き方

JpaRepository<エンティティのクラス型, 主キーのデータ型>

補足ですが、ログイン機能は実装しますが、今回は一般ユーザーのみ作成の流れとなります。管理者は作りません。

RoleRepository.java
package com.app.progTrack.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.app.progTrack.entity.Role;

public interface RoleRepository extends JpaRepository<Role, Integer>{

}
UserRepository.javaを作成する

ユーザー用のリポジトリを作成します。

Java
package com.app.progTrack.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.app.progTrack.entity.User;

public interface UserRepository extends JpaRepository<User, Integer>{

}

テストデータを挿入する

SQL
INSERT INTO roles (role_id, role_name) VALUES (1, 'MEMBER');

INSERT INTO users (user_id, user_name, email, password, enabled, role_id) VALUES(1, 'テスト 太郎', 'test@test.jp', '$2a$10$dXRJmKc50Mb6JsNh0lMw3u98xwoIrFF8ZyjwIT.GjCLjEhmGwFxxa', true, 1);

おわりに

一旦、今回はここまでとさせていただきます。

お読みいただきありがとうございました。

コメント