📌 글에서 사용한 코드 : 깃헙
이번 글에서는 지난 글의 연장선으로 Spring OAuth2 Authorization Server를 활용해서 만든 인증서버에서 로그인 페이지를 커스터마이징하는 방법에 대해서 알아보도록 하겠다.
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
build.gradle에 타임리프 라이브러리를 추가해준다.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Hello Spring OAuth2</title>
<link rel="stylesheet" th:href="@{/css/reset.css}">
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
<div id="login-page">
<div class="login-form">
<h1>로그인하쇼</h1>
<div class="message error" th:if="${param.error}">
잘못된 입력입니다. 아이디 또는 비밀번호를 다시 확인하세요.
</div>
<form th:action="@{/login}" method="post">
<div>
<input type="text" name="username" placeholder="아이디"/>
</div>
<div>
<input type="password" name="password" placeholder="비밀번호"/>
</div>
<button type="submit">로그인</button>
</form>
</div>
</div>
</body>
</html>
resources/templates/login.html
파일을 이렇게 만들어준다.
@import url(https://fonts.googleapis.com/css?family=Roboto:300);
body {
background: white;
font-family: "Roboto", sans-serif;
}
h1 {
color: black;
font-weight: bold;
font-size: 24px;
margin-bottom: 24px;
}
button {
width: 100%;
height: 48px;
border: none;
background-color: black;
color: white;
font-size: 16px;
font-weight: bold;
border-radius: 4px;
}
#login-page {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
}
.login-form {
text-align: center;
background: #ddd;
width: 100%;
max-width: 360px;
padding: 32px 24px;
border-radius: 12px;
margin: 18px;
}
.login-form input {
font-family: "Roboto", sans-serif;
outline: 0;
background: white;
width: 100%;
border: 0;
margin: 0 0 14px;
padding: 14px;
box-sizing: border-box;
font-size: 14px;
border-radius: 4px;
}
.login-form .message {
font-weight: bold;
margin: 16px 0;
color: #333;
font-size: 12px;
}
.login-form .error {
color: crimson;
}
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
순서대로 style.css
, reset.css
라는 이름으로, resources/static/css
폴더 안에 파일들을 만들어준다.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AuthController {
@GetMapping("/login")
public String login() {
return "login";
}
}
/login
으로 들어왔을 때, 커스터마이징한 로그인페이지에 접속할 수 있도록 컨트롤러를 하나 만들어준다.
이전 글에서 만들어줬던 SecurityConfig 클래스를 수정해준다.
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.debug(false)
.ignoring()
.requestMatchers("/images/**", "/css/**", "/assets/**", "/favicon.ico");
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable);
http.authorizeHttpRequests(authorize -> {
authorize
.requestMatchers("/").permitAll()
.requestMatchers("/error").permitAll() // 📌 추가
.anyRequest().authenticated();
});
http.formLogin(configurer -> { // 📌 추가
configurer.loginPage("/login").permitAll();
});
http.logout(configurer -> { // 📌 추가
configurer.logoutSuccessUrl("/");
});
return http.build();
}
localhost:9000/login으로 접속하면, 커스텀한 로그인 페이지가 정상적으로 노출되는 것을 확인할 수 있다.
로그인을 해보면, 로그인 기능도 잘 동작하는 것을 확인할 수 있다.