LoginSignup
0
0

Spring Boot学習④~パスワードのハッシュ化(SpringSecurity)~

Last updated at Posted at 2024-01-15

前→https://qiita.com/19960417akiho/items/2aa16ce876c4937b0cc3

以下の動画を参考に、ハンズオン形式でSpring BootでWebアプリを制作していきます。

今回はPart10。

パスワードのハッシュ化をSpringSecurityを用いて実装します。

まず、SpringSecurityを使うには、pom.xmlに情報を追加しなければなりません。

pom.xml

pom.xml
		<!-- PasswordEncoder(Spring Security)-->
		<dependency>
    		<groupId>org.springframework.security</groupId>
    		<artifactId>spring-security-core</artifactId>
		</dependency>

これでSpringSecurityの機能を用いることができます。

つぎに、configパッケージを作って、そのなかにBeanDifine.javaクラスを作っていきます。

正直Beanってなに?って感じですが、とりあえず動画の通りに実装してみて、疑問点をChatGPTに聞いてみます。

BeanDifine.java

BeanDifine.java
package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class BeanDifine {
	@Bean
	PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
}

まず@Configurationですが、これは@Beanとセットで付与するアノテーションだそうです。
クラスには@Configuration、その中のメソッドには@Beanって感じです。

動画の中では、
@Beanを付与したメソッドはDIコンテナに登録され、DI注入(@RequiredArgsConstructor配下でprivate finalしてインスタンス化)することができます」
と説明されています

頑張って調べてもいまいち理解できなかったので、以下は自分なりの理解です。

まず、@Beanとアノテーションがつけられたメソッドは特別扱いされます。

どう特別扱いされるかというと、そのメソッドの戻り値をキーとして、@RequiredArgsConstructorが付与されたクラスでも使うことができます。

今回で言うと、PasswordEncoderという型をキーとして、LoginControllerクラスでも使うことができるようになります。

LoginControllerクラスを見てみましょう

LoginController.java

LoginController.java
@Controller
@RequiredArgsConstructor
public class LoginController {
	
	/** PasswordEncoder*/
	private final PasswordEncoder passwordEncoder;


	@PostMapping("/login")
	public String login(Model model, LoginForm form) {
		var userInfo = service.searchUserById(form.getLoginId());
		var isCorrectUserAuth = userInfo.isPresent()
				&& passwordEncoder.matches(form.getPassword(), userInfo.get().getPassword());
		if(isCorrectUserAuth) {
			return "redirect:/menu";
		}else {
			// TODO エラーメッセージはプロパティファイルで一元管理する
			model.addAttribute("errorMsg","IDとPASSの組み合わせが間違っています。");
			return "login";
		}
	}
}

今回の実装に関係がある部分だけを記載しています。

まず、PasswordEncoder型のpasswordEncoderをフィールド化しています。

さっきの@Beanアノテーションがつけられていたのは、PasswordEncoderを戻り値にもつメソッドでした。

なので、passwordEncoderというフィールド内にpasswordEncoder()が装備されるというわけです。

また、psswrodEncoderにはprivate finalが修飾子としてついているので、@RequiredArgsConstructorによってLoginControllerの引数として組み込まれます。

つまり、LoginControllerがインスタンス化されるときに、引数のPasswordEncoder passwordEncoderもインスタンス化され、passwordEncoder()で実装したBCryptPasswordEncoderもインスタンス化されます。

これで、LoginControllerクラスの中でもBCryptPasswordEncoderが実装されたpasswordEncoderというインスタンスを利用することができます。

これでBCryptPasswordEncoderクラスがもっているハッシュ化に関するメソッドが使えます。

DBの方のパスワードは事前にハッシュ化しているので、単純に入力された生のパスワードとDBのパスワードを比較してもfalseが返ってきます。

&& passwordEncoder.matches(form.getPassword(), userInfo.get().getPassword());

上記のコードが生のパスワードとハッシュ化されたパスワードの比較です。

一つめの引数はformインスタンスが持っている生のパスワードを引っ張ってきて、二つ目の引数にはuserInfoインスタンスの情報からハッシュ化されたパスワードのみを引っ張ってきています。

次→https://qiita.com/19960417akiho/items/9bfc85a6c790a1fe9e22

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0