일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 크래시로그
- 자바스크립트
- net
- Font
- crashlog
- EUC-KR
- 데이터 전달
- 와이브로
- ClickOnce
- self-signed ssl
- JavaScript
- Antialiasing
- phpmailer
- docker
- MFC
- 한 번만 실행
- API
- 기념일관리
- .net
- GDI
- PDA
- 블루투스 헤드셋
- M8200
- plcrashreporter
- 설치제거
- C/C++
- C#
- php
- protobuf-c
- VS2008
- Today
- Total
~☆~ 우하하!!~ 개발블로그
[SpringBoot] Google 로그인시 회원가입 로직 추가 본문
https://iwoohaha.tistory.com/320 에서 Google 계정을 이용하여 로그인하는 과정을 살펴보았는데, 회원ID를 email 주소로 관리하고 있기 때문에 Google 로부터 전달받은 이메일 주소와 동일한 이메일 주소로 회원이 등록되어 있는 경우에 간단하게 로그인이 가능하게 되었다.
이번에는 회원가입되지 않은 이메일 주소의 구글 계정 정보가 들어온 경우에 해당 이메일 주소로 회원가입을 진행한 후에 로그인시키도록 기능을 변경해보려고 한다.
수정해야 할 주요 부분은 CustomOAuth2UserService 의 loadUser 함수 부분이다.
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
String provider = userRequest.getClientRegistration().getRegistrationId();
String email = oAuth2User.getAttribute("email");
String name = oAuth2User.getAttribute("name");
Optional<Member> member = memberMapper.GetMember(email);
if (member.isEmpty())
throw new UsernameNotFoundException("해당 이름의 사용자가 존재하지 않습니다: " + email);
//return oAuth2User;
return new User(member.get());
}
email 주소가 PK 로 구성되어 있는 member 테이블에서 해당 email 과 일치하는 데이터를 조회해서 없을 경우 회원가입이 되어 있지 않은 것으로 판단하고 있다.
회원가입이 되어 있지 않은 경우 해당 이메일 주소를 회원정보 테이블에 등록한 뒤 다시 조회한다면, 회원가입이 자동으로 이루어지게 된다.
그런데 이 경우 Not Null 로 구성되어 있는 password 컬럼값에 넣을 데이터가 없으므로 member 테이블의 password 컬럼을 Null 허용으로 수정해 주거나 임의의 값으로 password 컬럼값을 설정해줄 필요가 있다.
정답은 없는 문제이긴 하지만, GitHub 로그인, Apple 로그인, 카카오톡 로그인, 네이버 로그인 등으로 확장을 고려하여 다음과 같이 member 테이블의 구성을 조금 수정해보기로 하겠다.
password 는 Not Null 에서 Null 허용으로 수정하고, provider 컬럼을 추가하였다.
provider 컬럼에는 외부 인증을 하는 경우 외부 인증 정보 제공자 예를 들면, google, apple, kakao 등의 정보가 저장된다.
member 테이블이 수정되었으므로 domain 패키지 하위의 Member 클래스 멤버 역시 수정될 필요가 있다.
package com.woohahaapps.study.diary.domain;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
@AllArgsConstructor
@Getter
@Setter
@NoArgsConstructor
@Builder
public class Member {
@NotBlank(message = "이메일 주소는 필수값입니다.")
private String email;
// @NotBlank(message = "패스워드는 필수값입니다.")
private String password;
// @NotBlank(message = "이름은 필수값입니다.")
private String name;
private String role;
private String provider;// 외부인증정보 제공자
}
새로운 컬럼 추가에 따라 매퍼 함수 역시 수정되어야 한다.
/resources/mapper/MemberMapper.xml 에서 CreateMember, UpdateMember 가 수정될 대상이다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.woohahaapps.study.diary.mapper.MemberMapper">
<insert id="CreateMember" parameterType="Member">
insert into member (email, password, name, role, provider)
values (#{email}, #{password}, #{name}, #{role}, #{provider});
</insert>
<select id="GetMember" resultType="Member">
select
*
from member
where email=#{email};
</select>
<update id="UpdateMember" parameterType="Member">
update member
set
password = #{password}
, name = #{name}
, role = #{role}
, provider = #{provider}
where
email = #{email};
</update>
<delete id="DeleteMember">
delete from member
where
email = #{email};
</delete>
<select id="GetAllMembers" resultType="Member">
select
*
from member
order by
email
</select>
</mapper>
최종적으로 CustomOAuth2UserService 의 loadUser 함수는 아래와 같이 수정하면 된다.
package com.woohahaapps.study.diary.service;
import com.woohahaapps.study.diary.domain.Member;
import com.woohahaapps.study.diary.domain.User;
import com.woohahaapps.study.diary.mapper.MemberMapper;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private final MemberMapper memberMapper;
private final JavaMailSender mailSender;
public CustomOAuth2UserService(MemberMapper memberMapper, JavaMailSender mailSender) {
this.memberMapper = memberMapper;
this.mailSender = mailSender;
}
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
String provider = userRequest.getClientRegistration().getRegistrationId();
String email = oAuth2User.getAttribute("email");
String name = oAuth2User.getAttribute("name");
Optional<Member> member = memberMapper.GetMember(email);
if (member.isEmpty()) {
// throw new UsernameNotFoundException("해당 이름의 사용자가 존재하지 않습니다: " + email);
Member newmember = new Member();
newmember.setEmail(email);
newmember.setName(name);
newmember.setRole("ROLE_USER");
newmember.setProvider(provider);
memberMapper.CreateMember(newmember);
// Mail 발송
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(newmember.getEmail());
message.setSubject("[signUp] diary 에 회원가입되었습니다");
message.setText(String.format("email: %s\nname: %s", newmember.getEmail(), newmember.getName()));
mailSender.send(message);
return new User(newmember);
}
//return oAuth2User;
return new User(member.get());
}
}
이제 프로그램을 실행시켜서 구글 계정으로 woohaha.apps@gmail.com 계정을 선택해보면 신규 회원으로 등록됨과 동시에 로그인처리 될 것이다.
이 경우 패스워드가 등록되지 않기 때문에 패스워드 입력 방식으로는 로그인할 수가 없게 된다.
'SpringBoot' 카테고리의 다른 글
[SpringBoot] Naver 로그인 구현 (1차 시도) (0) | 2024.11.19 |
---|---|
[연재] SpringBoot diary - jwt 로그인으로 변경, 로그아웃까지 수정 (0) | 2024.11.15 |
[연재] SpringBoot diary - Spring Security remember-me, logout 처리 재정리 (0) | 2024.11.15 |
[연재] SpringBoot diary - 역할(ROLE) 관리 기능 추가 (0) | 2024.11.15 |
[연재] SpringBoot diary - RestController 에서 ResponseEntity 를 리턴하자. (0) | 2024.11.15 |