Published 2021. 8. 5. 20:27
테이블 생성 |
-> 저번장에 생성한 member 테이블은 삭제처리
-> TB_AUTHORITES, TB_CODE, TB_GRP_CODE, TB_USERS 테이블을 생성
TB_AUTHORITIES 생성문 (권한테이블) |
CREATE TABLE `tb_authorities` (
`AUTH_IDX` int NOT NULL AUTO_INCREMENT COMMENT '인덱스',
`USER_ID` varchar(45) DEFAULT NULL COMMENT '사용자 아이디',
`AUTHORITY` varchar(45) DEFAULT NULL COMMENT '권한',
PRIMARY KEY (`AUTH_IDX`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='권한테이블'
TB_CODE 생성문 (코드 테이블) |
CREATE TABLE `tb_code` (
`CODE_IDX` int NOT NULL AUTO_INCREMENT COMMENT '인덱스',
`CODE_NO` varchar(45) NOT NULL COMMENT '코드번호',
`CODE_NAME` varchar(45) DEFAULT NULL,
`CODE_EXP` varchar(45) DEFAULT NULL COMMENT '코드명',
PRIMARY KEY (`CODE_IDX`,`CODE_NO`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='코드 테이블'
TB_GRP_CODE 생성문 (코드 그룹 테이블) |
CREATE TABLE `tb_grp_code` (
`GRP_CODE_IDX` int NOT NULL AUTO_INCREMENT COMMENT '인덱스',
`GRP_CD_NO` varchar(20) DEFAULT NULL COMMENT '그룹코드 번호',
`GRP_CD_EXP` varchar(45) DEFAULT NULL COMMENT '그룹 코드명',
PRIMARY KEY (`GRP_CODE_IDX`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='코드 그룹 테이블'
TB_USERS 테이블 생성문 (사용자 테이블) |
CREATE TABLE `tb_users` (
`USER_IDX` int NOT NULL AUTO_INCREMENT COMMENT '인덱스',
`USER_ID` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '사용자 아이디',
`PASSWORD` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '패스워드',
`USER_NAME` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '사용자 이름',
`EMAIL` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '이메일',
`HAND_PHONE_NO` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '핸드폰번호',
`USE_YN` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '사용여부',
PRIMARY KEY (`USER_IDX`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3
TB_GRP_CODE 데이터 |
-> 권한이라는 그룹 데이터를 생성
TB_CODE 데이터 |
-> 권한이라는 그룹 데이터 안에 관리자, 사용자가 있다고 생각하면됨
롬복 설정 |
intelij에서는 lombok을 gradle에 추가를 했을때는 바로 적용이 됬었는데 sts에서는 적용이 안되는 경우가 있어서 jar를 직접 실행해서 sts 경로를 설정하였음 |
https://projectlombok.org/download
-> 해당 사이트에서 롬복 다운로드
-> 이후 해당 경로에 가서 java -jar lombok.jar 실행
-> Specify location 클릭후 이클립스 설치되어있는 경로를 선택후 install / update 클릭
-> 이후 이클립스 껏다가 다시키면 적용이 됨
admin 프로젝트 build.gradle 수정 |
build.gradle |
apply plugin: 'war'
def timestamp = new Date().format('yyMMddHHmm')
bootWar.enabled = false // (1)
war.enabled = true // (2)
war {
archiveName = "admin-${version}-"+timestamp+".war"
}
dependencies {
implementation project(':core')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation('org.springframework.security:spring-security-test')
//db
runtimeOnly 'mysql:mysql-connector-java'
// MyBatis
implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2")
testImplementation('org.springframework.boot:spring-boot-starter-test')
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools
implementation group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '2.2.6.RELEASE'
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
implementation group: 'org.springframework.security', name: 'spring-security-core', version: '5.3.0.RELEASE'
implementation group: 'org.springframework.security', name: 'spring-security-taglibs', version: '5.3.0.RELEASE'
// Apache Http Requests
implementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.12' // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
// Tiles Setting
implementation group: 'org.apache.tiles', name: 'tiles-jsp', version: '3.0.8' // https://mvnrepository.com/artifact/org.apache.tiles/tiles-jsp
implementation group: 'org.apache.tiles', name: 'tiles-core', version: '3.0.8' // https://mvnrepository.com/artifact/org.apache.tiles/tiles-core
/* Jsp Setting */
implementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.0.31' // https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper
implementation group: 'org.apache.taglibs', name: 'taglibs-standard-impl', version: '1.2.5' // https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl
providedRuntime group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1' // https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
implementation group: 'javax.servlet', name: 'jstl' // https://mvnrepository.com/artifact/javax.servlet/jstl
/* gson */
implementation 'com.google.code.gson:gson:2.8.6'
}
-> security 추가하기, gradle 수정하면 refresh gradle 꼭 해줘야함!
core 프로젝트에 build.gradle 수정 |
build.gradle |
bootJar{
enabled = false;
}
jar {
enabled = true;
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
//security core
implementation group: 'org.springframework.security', name: 'spring-security-core', version: '5.3.1.RELEASE'
}
core 프로젝트안에 entity 패키지 생성후 그안에 UserAuthority.java, UserInfo.java 생성 |
UserAuthority.java |
package com.board.entity;
import org.springframework.security.core.GrantedAuthority;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserAuthority implements GrantedAuthority {
/**
*
*/
private static final long serialVersionUID = 1L;
private String authority;
private String authorityNm;
@Override
public String getAuthority() {
// TODO Auto-generated method stub
return this.authority;
}
}
-> 사용자 권한 관련 vo
UserInfo.java |
package com.board.entity;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserInfo implements UserDetails {
/**
*
*/
private static final long serialVersionUID = 1L;
//사용자 id
private String userId;
//사용자 이름
private String userName;
//패스워드
private String password;
//이메일
private String email;
//핸드폰 반호
private String handPhoneNo;
//사용여부
private String useYn;
//권한 list
public List<UserAuthority> authorities;
//권한
public String authority;
//권한 이름
public String authorityNm;
public String auth;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return userName;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
-> 사용자 관련 vo
core 프로젝트 안에 dao 패키지 안에 UserMapper.java 생성 |
UserMapper.java |
package com.board.dao;
import com.board.entity.UserInfo;
import com.board.entity.UserAuthority;
public interface UserMapper {
//사용자 정보 조회
UserInfo getUserInfo(String userId);
//사용자 권한 조회
UserAuthority getUserAuthorities(String userId);
//사용자 등록
public int insertUser(UserInfo userinfo);
//사용자 권한 등록
public int insertUserAuth(UserInfo userinfo);
//사용자 중복체크
int duplicateUserCheck(String userId);
}
application.properties 수정 |
# Deploy profile ( prod, stage, dev, local )
spring.profiles.active=local
# encoding
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
#View Configuration
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
# model 프로퍼티 camel case 설정
mybatis.configuration.map-underscore-to-camel-case=true
# xml파일 result type에 패키지명을 생략할 수 있도록 alias 설정
mybatis.type-aliases-package=com.board.entity
-> xml에서 resultType를 읽을수 있도록 설정
resources 폴더안에 dao 패키지안에 UserMapper.xml 생성 |
UserMapper.xml |
<?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">
<!-- FAQ SQL Mapper -->
<mapper namespace="com.board.dao.UserMapper">
<!-- 사용자 정보 조회 -->
<select id="getUserInfo" parameterType="String" resultType="UserInfo">
SELECT
USER_ID
,USER_NAME
,PASSWORD
,EMAIL
,HAND_PHONE_NO
,USE_YN
FROM
TB_USERS
WHERE
USER_ID = #{userId}
</select>
<!-- 사용자 권한 조회 -->
<select id="getUserAuthorities" parameterType="String" resultType="UserAuthority">
SELECT
TA.AUTHORITY
,(SELECT CODE_EXP FROM TB_CODE TCD WHERE TCD.CODE_NO = '200' AND TCD.CODE_NAME = TA.AUTHORITY) AS AUTHORITY_NM
FROM
TB_AUTHORITIES TA
WHERE
TA.USER_ID = #{userId}
</select>
<!-- 사용자 등록 -->
<insert id="insertUser" parameterType="UserInfo">
INSERT INTO
TB_USERS(
USER_ID
,PASSWORD
,USER_NAME
,EMAIL
,HAND_PHONE_NO
,USE_YN
)
VALUES(
#{userId}
,#{password}
,#{userName}
,#{email}
,#{handPhoneNo}
,'1'
)
</insert>
<!-- 사용자 중복체크 -->
<select id="duplicateUserCheck" parameterType="String" resultType="int">
SELECT
COUNT(*)
FROM
TB_USERS
WHERE
USER_ID = #{userId}
</select>
<!-- 사용자 권한 등록 -->
<insert id="insertUserAuth" parameterType="UserInfo">
INSERT INTO
TB_AUTHORITIES(
USER_ID
,AUTHORITY
)
VALUES(
#{userId}
,'USER'
)
</insert>
</mapper>
core 프로젝트에 service패키지에 LoginService 생성 |
LoginService.java |
package com.board.service;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.board.dao.UserMapper;
import com.board.entity.UserInfo;
@Service
public class LoginService {
@Autowired
UserMapper userMapper;
@Autowired
PasswordEncoder passwordEncoder;
public Map<String, Object> checkLoginInsert(UserInfo userInfo) {
Map<String, Object> result = new HashMap<String, Object>();
//0이면 중복되는 아이디 없음
int duplicateCheck = userMapper.duplicateUserCheck(userInfo.getUserId());
//신규등록
if(duplicateCheck == 0) {
//패스워드 bcrypt 암호화
String password = passwordEncoder.encode(userInfo.getPassword());
userInfo.setPassword(password);
//사용자 등록
userMapper.insertUser(userInfo);
result.put("resultCode", "00");
result.put("resultMsg", "정상적으로 회원이 등록되었습니다.");
//사용자 권한 등록
userMapper.insertUserAuth(userInfo);
}
//중복된 아이디가 있으므로 에러
else {
result.put("resultCode", "99");
result.put("resultMsg", "중복된 아이디가 있습니다. 아이디를 다시 입력해주세요.");
}
return result;
}
}
admin 프로젝트에 exception 패키지 생성후 안에 파일 생성 |
UserIdException.java |
package com.board.exception;
import org.springframework.security.core.AuthenticationException;
/**
* The Class CUserNotFoundException.
*/
public class UserIdException extends AuthenticationException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/**
* Instantiates a new c user not found exception.
*
* @param msg the msg
* @param t the t
*/
public UserIdException(String msg, Throwable t) {
super(msg, t);
}
/**
* Instantiates a new c user not found exception.
*
* @param msg the msg
*/
public UserIdException(String msg) {
super(msg);
}
}
UserAuthException.java |
package com.board.exception;
import org.springframework.security.core.AuthenticationException;
/**
* The Class CUserNotFoundException.
*/
public class UserAuthException extends AuthenticationException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/**
* Instantiates a new c user not found exception.
*
* @param msg the msg
* @param t the t
*/
public UserAuthException(String msg, Throwable t) {
super(msg, t);
}
/**
* Instantiates a new c user not found exception.
*
* @param msg the msg
*/
public UserAuthException(String msg) {
super(msg);
}
}
admin 프로젝트 common 패키지에 CoTopComponent.java 생성 |
CoTopComponent.java |
package com.board.common;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import com.google.gson.JsonObject;
/* 최상위 컴포넌트 */
public abstract class CoTopComponent {
protected void writeResponse(HttpServletResponse res, JsonObject jsonObject) throws IOException{
writeResponse(res, jsonObject.toString());
}
protected void writeResponse(HttpServletResponse res, String message) throws IOException{
res.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
PrintWriter pw = res.getWriter();
pw.write(message);
pw.close();
}
}
config 패키지안에 ClientAuthenticationProvider.java, LoginSuccessHandler.java, LoginFailHandler.java, SpringSecuritySessionRegistImpl.java, SecurityConfig.java 생성 |
AdminAuthenticationProvider.java |
package com.board.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import com.board.dao.UserMapper;
import com.board.entity.UserAuthority;
import com.board.entity.UserInfo;
import com.board.exception.UserAuthException;
import com.board.exception.UserIdException;
import org.springframework.security.crypto.password.PasswordEncoder;
/** 로그인 provider */
@Component
public class AdminAuthenticationProvider implements AuthenticationProvider{
@Autowired
UserMapper userMapper;
@Autowired
PasswordEncoder passwordEncoder;
@SuppressWarnings("unchecked")
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UsernamePasswordAuthenticationToken authToken = (UsernamePasswordAuthenticationToken) authentication;
//아이디
String id = (authToken.getName()).toUpperCase();
//비밀번호
String pwd = (String) authToken.getCredentials();
//해당 사용자 정보 조회
UserInfo userInfo = userMapper.getUserInfo(id);
//해당 사용자가 있을경우
if(userInfo != null ) {
//입력한 비밀번호가 현재 비밀번호와 같지 않으면
if(!(passwordEncoder.matches(pwd, userInfo.getPassword()))) {
throw new UserIdException("접속 할 수 없습니다. \n아이디 또는 비밀번호를 확인해주세요.");
}
//입력한 비밀번호가 현재 비밀번호와 같으면
else {
List<UserAuthority> authorities = new ArrayList<>();
//권한 조회
UserAuthority getUserAuthorities = userMapper.getUserAuthorities(authToken.getName());
//권한이 있을경우
if(getUserAuthorities != null) {
UserAuthority auth = new UserAuthority();
auth.setAuthority(getUserAuthorities.getAuthority());
auth.setAuthorityNm(getUserAuthorities.getAuthorityNm());
authorities.add(auth);
userInfo.setAuthorities(authorities);
}
//권한이 없을 경우
else {
throw new UserAuthException("접속권한이 없습니다. \n관리자에게 권한을 요청해주세요.");
}
}
}
//해당 사용자가 없을경우
else {
throw new UserIdException("접속 할 수 없습니다. \n아이디 또는 비밀번호를 확인해주세요.");
}
List<GrantedAuthority> authorities = (List<GrantedAuthority>) userInfo.getAuthorities();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userInfo, "1", authorities);
return token;
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
LoginSuccessHandler.java |
package com.board.config;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import com.board.common.CoTopComponent;
import com.board.entity.UserInfo;
import com.google.gson.JsonObject;
/* 로그인 성공시 타는 handler */
@Component
public class LoginSuccessHandler extends CoTopComponent implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication auth) throws IOException, ServletException {
//default 성공
String resultCode = "00";
HttpSession session = request.getSession(true);
session.setMaxInactiveInterval(60 * 60 * 3);
session.setAttribute("sessUserInfo",((UserInfo) auth.getPrincipal()));
session.setAttribute("authority",((UserInfo) auth.getPrincipal()).getAuthority());
session.setAttribute("authorityNm",((UserInfo) auth.getPrincipal()).getAuthorityNm());
session.setAttribute("auth",((UserInfo) auth.getPrincipal()).getAuth());
//Response 결과 값을 넣어줌
JsonObject loginResult = new JsonObject();
loginResult.addProperty("resultCode", resultCode);
loginResult.addProperty("targetUrl", request.getContextPath()+"/");
//응답 전송
writeResponse(response, loginResult);
}
}
LoginFailureHandler.java |
package com.board.config;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import com.board.common.CoTopComponent;
import com.board.exception.UserAuthException;
import com.board.exception.UserIdException;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
/* 로그인 실패시 타는 핸들러 */
@Slf4j
@Component
public class LoginFailureHandler extends CoTopComponent implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
writeResponse(response, parseException(request.getParameter("un"), exception));
}
private JsonObject parseException(String userName, AuthenticationException exception) {
String errCode = "99";
String errMsg = exception.getMessage();
//존재하지 않는 아이디
if( exception instanceof UserIdException) {
log.error("존재하지않는 아이디입니다.");
}
//권한이 없을경우
else if( exception instanceof UserAuthException) {
log.error("권한이 없는 아이디입니다.");
}
JsonObject result = new JsonObject();
result.addProperty("resultCode", errCode);
result.addProperty("resultMessage", errMsg);
return result;
}
}
SpringSecuritySessionRegistImpl.java |
package com.board.config;
import org.springframework.security.core.session.SessionRegistryImpl;
public class SpringSecuritySessionRegistImpl extends SessionRegistryImpl {
}
SecurityConfig.java |
package com.board.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.board.common.Constants;
import com.board.common.Url;
/* 시큐리티 설정 */
@Configuration
@EnableWebSecurity
@ComponentScan(value = Constants.APP_DEFAULT_PACKAGE_NAME)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private LoginSuccessHandler loginSucessHandler;
@Autowired
private LoginFailureHandler loginFailureHandler;
/* configure */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new AdminAuthenticationProvider());
super.configure(auth);
}
/* http 요청 검사 */
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/**").permitAll() //로그인, 회원가입 접속허용
.antMatchers("/resource/**/images/**").permitAll() //이미지
.anyRequest().authenticated()
.and()
//로그인 화면 설정
.formLogin()
.permitAll()
.loginPage(Url.AUTH.LOGIN)
.loginProcessingUrl(Url.AUTH.LOGIN_PROC)
.successHandler(loginSucessHandler)
.failureHandler(loginFailureHandler)
.usernameParameter(USERNAME_PARAM)
.passwordParameter(PASSWORD_PARAM)
.and()
.logout()
.logoutUrl(Url.AUTH.LOGOUT_PROC)
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()
//세션관리
.sessionManagement()
.maximumSessions(200) //세션 허용 갯수
.expiredUrl(Url.AUTH.LOGIN) //세션 만료시 이동할 페이지
.sessionRegistry(sesionRegistry())
.maxSessionsPreventsLogin(true); //동시 로그인 차단, false인 경우 기존 세션 만료
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(Constants.STATIC_RESOURCES_URL_PATTERS)
.antMatchers(HttpMethod.GET, "/exception/**");
super.configure(web);
}
//패스워드 암호화
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SessionRegistry sesionRegistry() {
return new SpringSecuritySessionRegistImpl();
}
/* 관리자 아이디 파라미터 이름 */
public static final String USERNAME_PARAM = "un";
/* 관리자 비밀번호 파라미터 이름 */
public static final String PASSWORD_PARAM = "up";
}
Constants.java 수정 |
package com.board.common;
/** 서비스에 사용되는 공통변수 */
public final class Constants {
//프로젝트 패키지 이름
public final static String APP_DEFAULT_PACKAGE_NAME = "com.board";
//dao 패키지 경로
public final static String MAPPER_PACKAGE = Constants.APP_DEFAULT_PACKAGE_NAME+".dao";
//Tiles xml 경로
public final static String[] TILES_LAYOUT_XML_PATH = {
"WEB-INF/tiles.xml"
};
//Runtime에서 JSP의 refresh 적용 여부
public final static boolean REFRESH_JSP_ON_RUNTIME = true;
/** 정적 리소스 종류 */
private final static String[] STATIC_RES = {
"/js"
,"/css"
,"/images"
,"/favicon"
,"/template"
,"/font"
,"/robots.txt"
,"/favicon.ico"
};
/** 정적 리소스 매핑 URL 패턴 (위에꺼랑 순서 맞아야함) */
public final static String[] STATIC_RESOURCES_URL_PATTERS = {
STATIC_RES[0]+"/**"
,STATIC_RES[1]+"/**"
,STATIC_RES[2]+"/**"
,STATIC_RES[3]+"/**"
,STATIC_RES[4]+"/**"
,STATIC_RES[5]+"/**"
,STATIC_RES[6]
,STATIC_RES[7]+"/**"
};
}
Url.java 수정 |
package com.board.common;
/* api url 정의 */
public final class Url {
public static final String TILES_ROOT = "/tiles/view";
public static final String TILES_AJAX = "/tiles/ajax";
/* 로그인 */
public static final class AUTH {
/* 로그인 url */
public static final String LOGIN = "/auth/login";
/* 로그인 jsp */
public static final String LOGIN_JSP = TILES_ROOT + "/auth/login";
/* 회원가입 url */
public static final String JOIN = "/auth/join";
/* 회원가입 jsp */
public static final String JOIN_JSP = TILES_ROOT + "/auth/join";
/* 사용자 등록 */
public static final String INSERT_USER = "/auth/insertUser";
/* 로그인 인증 요청 */
public static final String LOGIN_PROC = "/auth/login-proc";
/* 로그아웃 요청 */
public static final String LOGOUT_PROC = "/auth/logout-proc";
}
/* 메인 화면 */
public static final class MAIN {
/* 로그인 url */
public static final String MAIN = "/";
/* 로그인 jsp */
public static final String MAIN_JSP = TILES_ROOT + "/main/list";
}
}
admin 프로젝트의 LoginController 수정 |
LoginController.java |
package com.board.controller;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.board.common.Url;
import com.board.entity.UserInfo;
import com.board.service.LoginService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class LoginController {
@Autowired
LoginService loginService;
//로그인 화면
@GetMapping(value= {Url.AUTH.LOGIN})
public String login() {
return Url.AUTH.LOGIN_JSP;
}
//회원가입 화면
@GetMapping(Url.AUTH.JOIN)
public String join() {
return Url.AUTH.JOIN_JSP;
}
//메인화면
@GetMapping(Url.MAIN.MAIN)
public String main() {
return Url.MAIN.MAIN_JSP;
}
//사용자 등록
@PostMapping(Url.AUTH.INSERT_USER)
@ResponseBody
public Map<String, Object> insertUser(@ModelAttribute UserInfo userInfo) {
//회원 등록
return loginService.checkLoginInsert(userInfo);
}
}
login.jsp, login-js,jsp 수정 |
login.jsp |
<%@ page language="java" session="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/WEB-INF/template/constants.jsp"%>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<link rel="stylesheet" type="text/css" href="${ctxPath}/css/loginForm.css"/>
<div class="wrapper fadeInDown">
<div id="formContent">
<!-- Tabs Titles -->
<!-- Icon -->
<div class="fadeIn first">
로그인
</div>
<!-- Login Form -->
<form>
<input type="text" id="loginId" class="fadeIn second" name="un" placeholder="아이디를 입력해주세요" required>
<input type="text" id="loginPw" class="fadeIn third" name="up" placeholder="비밀번호를 입력해주세요" required>
<input type="button" class="fadeIn fourth" value="Log In" onclick="loginSubmit()">
</form>
<!-- Remind Passowrd -->
<div id="formFooter">
<a class="underlineHover" href="/auth/join">회원가입</a>
</div>
</div>
</div>
login-js.jsp |
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<script>
//로그인 submit
function loginSubmit(){
var params = {
'un' : $.trim($("#loginId").val())
,'up' : $("#loginPw").val()
}
console.log(params);
$.ajax({
type : 'POST'
,url : '/auth/login-proc'
,dataType : 'json'
,data : params
,success : function(result) {
console.log(result);
if(result.resultCode != "00"){
alert(result.resultMessage);
}
else{
location.href=result.targetUrl;
}
},
error: function(request, status, error) {
}
})
}
</script>
join.jsp |
<%@ page language="java" session="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/WEB-INF/template/constants.jsp"%>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<link rel="stylesheet" type="text/css" href="${ctxPath}/css/loginForm.css"/>
<div class="wrapper">
<div id="formContent">
<!-- Tabs Titles -->
<!-- Icon -->
<div class="fadeIn first">
회원가입
</div>
<!-- Login Form -->
<form>
<input type="text" id="userId" class="fadeIn second" name="login" placeholder="아이디를 입력해주세요." required>
<input type="text" id="password" class="fadeIn third" name="login" placeholder="비밀번호를 입력해주세요." required>
<input type="text" id="userName" class="fadeIn third" name="login" placeholder="이름을 입력해주세요.">
<input type="text" id="email" class="fadeIn third" name="login" placeholder="이메일을 입력해주세요.">
<input type="text" id="handPhoneNo" class="fadeIn third" name="login" placeholder="핸드폰번호를 입력해주세요.">
<input type="button" class="fadeIn fourth" value="Join" onclick="join()">
</form>
<!-- Remind Passowrd -->
<div id="formFooter">
<a class="underlineHover" href="/auth/login">뒤로가기</a>
</div>
</div>
</div>
join-js.jsp |
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<script>
//로그인 submit
function join(){
var params = {
'userId' : $("#userId").val()
,'password' : $("#password").val()
,'userName' : $("#userName").val()
,'email' : $("#email").val()
,'handPhoneNo' : $("#handPhoneNo").val()
}
console.log(params);
$.ajax({
type : 'POST'
,url : '/auth/insertUser'
,dataType : 'json'
,data : params
,success : function(result) {
alert(result.resultMsg);
if(result.resultCode == '00'){
location.href="/auth/login";
}
},
error: function(request, status, error) {
}
})
}
</script>
views 아래 main폴더 생성후 list.jsp, list-js.jsp 생성 |
list.jsp |
<%@ page language="java" session="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/WEB-INF/template/constants.jsp"%>
<body>
메인입니다. <br>
<button onclick="location.href='/auth/logout-proc'">로그아웃</button>
</body>
list-js.jsp |
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<script>
</script>
로그인화면 |
회원등록 화면 |
Join버튼 클릭
db에 저장되어있는지 확인 |
로그인시도 (아이디또는 패스워드 일부러 틀렸을때) |
해당계정에 권한이 없을경우 |
로그인 성공시 |
->로그아웃 버튼 클릭시 로그아웃이 되는것을 볼수있습니다.
다음포스팅 에서는 게시판을 개발해서 적용해보겠습니다. 감사합니다.
'스프링' 카테고리의 다른 글
[Spring] sts4에서 jsp 사용하기 (0) | 2021.08.12 |
---|---|
[Spring Boot] 4. 게시판 CRUD, 페이징처리 (Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (0) | 2021.08.07 |
[Spring Boot] 2. TILES 설정 (Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (0) | 2021.08.03 |
[Spring Boot] 1. 멀티프로젝트 세팅 (Gradle+Mybatis+멀티프로젝트+MYSQL+STS) (4) | 2021.08.01 |
[Spring] Requset 메소드 사용하기 (0) | 2021.07.05 |