ㅇㅇ 로그인아웃 방식 변경
This commit is contained in:
parent
3dcb077e2f
commit
e39a7d1fd3
@ -22,6 +22,6 @@ COPY ${JAR_FILE} app.jar
|
|||||||
EXPOSE 443
|
EXPOSE 443
|
||||||
#EXPOSE 27012
|
#EXPOSE 27012
|
||||||
#EXPOSE 3307
|
#EXPOSE 3307
|
||||||
ENTRYPOINT ["java","-Dtelegram.bot.key=${BOT_KEY}","-Dtelegram.my.id=${TG_MINE}","-Dtelegram.target.id=${TG_TARGET_ID}","-Dweather.api.key=${WEATHER_KEY}","-Dspring.datasource.url=${DATASOURCE_URL}" ,"-Dspring.data.mongodb.uri=${MONGODB_HOST}","-Dspring.data.mongodb.database=${MONGODB_NAME}","-Dspring.datasource.username=${MRA_ADMIN}","-Dspring.datasource.password=${MRA_PW}","-Dresource.handler=${RESOURCE_HANDLER}","-Dresource.location=${RESOURCE_LOCATION}","-Dimage.upload.path=${IMAGE_UPLOAD_PATH}","-Dapi.gg.place=${GAPI_KEY}","-jar","app.jar"]
|
|
||||||
#ENTRYPOINT ["java","-jar","app.jar","-Dspring-boot.run.arguments=--telegram.bot.key=${BOT_KEY}, --telegram.my.id=${TG_MINE}, --telegram.target.id=${TG_TARGET_ID}, --weather.api.key=${WEATHER_KEY}"]
|
#ENTRYPOINT ["java","-jar","app.jar","-Dspring-boot.run.arguments=--telegram.bot.key=${BOT_KEY}, --telegram.my.id=${TG_MINE}, --telegram.target.id=${TG_TARGET_ID}, --weather.api.key=${WEATHER_KEY}"]
|
||||||
|
ENTRYPOINT ["java","-Dtelegram.bot.key=${BOT_KEY}","-Dtelegram.my.id=${TG_MINE}","-Dtelegram.target.id=${TG_TARGET_ID}","-Dweather.api.key=${WEATHER_KEY}","-Dspring.datasource.url=${DATASOURCE_URL}" ,"-Dspring.data.mongodb.uri=${MONGODB_HOST}","-Dspring.data.mongodb.database=${MONGODB_NAME}","-Dspring.datasource.username=${MRA_ADMIN}","-Dspring.datasource.password=${MRA_PW}","-Dresource.handler=${RESOURCE_HANDLER}","-Dresource.location=${RESOURCE_LOCATION}","-Dimage.upload.path=${IMAGE_UPLOAD_PATH}","-Dapi.gg.place=${GAPI_KEY}","-jar","app.jar"]
|
||||||
#-Dtelegram.bot.key=bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w -Dtelegram.target.id=71476436 -Dtelegram.my.id=71476436 -Dweather.api.key=de574a260b1f474d99955729241909 -Dspring.datasource.url=jdbc:mariadb://mra.sbspace.synology.me -Dspring.data.mongodb.uri=mongodb://lun_admin:VioPup*383@mongo.sbspace.synology.me/?wtimeoutMS=300&connectTimeoutMS=500&socketTimeoutMS=200 -Dspring.data.mongodb.database=lun_db -Dspring.datasource.username=lun_admin -Dspring.datasource.password=VioPup*383 -Dresource.handler=/blog/post/image/** -Dresource.location=file:///imgUpload -Dimage.upload.path=imgUpload
|
#-Dtelegram.bot.key=bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w -Dtelegram.target.id=71476436 -Dtelegram.my.id=71476436 -Dweather.api.key=de574a260b1f474d99955729241909 -Dspring.datasource.url=jdbc:mariadb://mra.sbspace.synology.me -Dspring.data.mongodb.uri=mongodb://lun_admin:VioPup*383@mongo.sbspace.synology.me/?wtimeoutMS=300&connectTimeoutMS=500&socketTimeoutMS=200 -Dspring.data.mongodb.database=lun_db -Dspring.datasource.username=lun_admin -Dspring.datasource.password=VioPup*383 -Dresource.handler=/blog/post/image/** -Dresource.location=file:///imgUpload -Dimage.upload.path=imgUpload
|
||||||
|
|||||||
@ -50,6 +50,8 @@ dependencies {
|
|||||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||||
|
implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
|
||||||
|
|
||||||
implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
|
implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
|
||||||
implementation ("org.jsoup:jsoup:1.18.1")
|
implementation ("org.jsoup:jsoup:1.18.1")
|
||||||
|
|
||||||
@ -104,6 +106,7 @@ tasks.withType<Test> {
|
|||||||
|
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
|
archiveFileName.set("app.jar")
|
||||||
manifest {
|
manifest {
|
||||||
attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
|
attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import org.springframework.beans.factory.annotation.Value
|
|||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.http.CacheControl
|
import org.springframework.http.CacheControl
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@ -28,10 +30,13 @@ class AppConfig : WebMvcConfigurer {
|
|||||||
registry.addResourceHandler(resourceHandler).addResourceLocations(resourceLocation).setCacheControl(cacheControl)
|
registry.addResourceHandler(resourceHandler).addResourceLocations(resourceLocation).setCacheControl(cacheControl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addInterceptors(registry: InterceptorRegistry) {
|
@Bean
|
||||||
registry.addInterceptor(authInterceptor())
|
fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()
|
||||||
super.addInterceptors(registry)
|
// override fun addInterceptors(registry: InterceptorRegistry) {
|
||||||
}
|
// registry.addInterceptor(authInterceptor())
|
||||||
|
// .addPathPatterns("**/*.bs", "**/*.bjx")
|
||||||
|
// super.addInterceptors(registry)
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
// @Bean
|
// @Bean
|
||||||
|
|||||||
@ -8,9 +8,9 @@ import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.ApiKeyWordKey
|
|||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
||||||
import kr.lunaticbum.back.lun.model.UserManager
|
import kr.lunaticbum.back.lun.model.UserManager
|
||||||
import kr.lunaticbum.back.lun.service.JwtService
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.lang.Nullable
|
import org.springframework.lang.Nullable
|
||||||
|
import org.springframework.security.web.authentication.RememberMeServices
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.web.servlet.HandlerInterceptor
|
import org.springframework.web.servlet.HandlerInterceptor
|
||||||
@ -19,12 +19,8 @@ import org.springframework.web.servlet.ModelAndView
|
|||||||
@Component
|
@Component
|
||||||
class BumsInterceptor : HandlerInterceptor {
|
class BumsInterceptor : HandlerInterceptor {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
lateinit var jwtService : JwtService
|
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var globalEvv : GlobalEnvironment
|
lateinit var globalEvv : GlobalEnvironment
|
||||||
@Autowired
|
|
||||||
lateinit var userManager: UserManager
|
|
||||||
|
|
||||||
val WRITE_PERMISSION_KEY = "PERMISSION"
|
val WRITE_PERMISSION_KEY = "PERMISSION"
|
||||||
|
|
||||||
@ -36,9 +32,13 @@ class BumsInterceptor : HandlerInterceptor {
|
|||||||
// println("==================== BEGIN ====================")
|
// println("==================== BEGIN ====================")
|
||||||
// println("Request URL ===> " + request.requestURL)
|
// println("Request URL ===> " + request.requestURL)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
return super.preHandle(request, response, handler)
|
return super.preHandle(request, response, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Autowired
|
||||||
|
// lateinit var rememberMeServices: RememberMeServices
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
override fun postHandle(
|
override fun postHandle(
|
||||||
@ -47,68 +47,9 @@ class BumsInterceptor : HandlerInterceptor {
|
|||||||
handler: Any,
|
handler: Any,
|
||||||
@Nullable modelAndView: ModelAndView?
|
@Nullable modelAndView: ModelAndView?
|
||||||
) {
|
) {
|
||||||
var skippResourcesExtension = arrayListOf(".ajax",".js",".css","/tlg/",".api","error").filter { request.requestURI.contains(it)}.size > 0
|
// if(remeberMe && authResult != null) {
|
||||||
if (!skippResourcesExtension) {
|
// rememberMeServices.loginSuccess(httpServletRequest, responce, authResult)
|
||||||
if (request.requestURI.contains("logout") == false && !request.cookies.isNullOrEmpty() && request.cookies.filter {
|
// }
|
||||||
it.name.equals(
|
|
||||||
"access"
|
|
||||||
) && it.value.length > 0
|
|
||||||
}.size > 0) {
|
|
||||||
var refreshOk = false;
|
|
||||||
var accessOk = false;
|
|
||||||
var access: Cookie? = null
|
|
||||||
var refresh: Cookie? = null
|
|
||||||
request.cookies.forEach {
|
|
||||||
if (it.name.equals("access", true) && jwtService.validateAccessToken(it.value)) {
|
|
||||||
access = it
|
|
||||||
accessOk = true
|
|
||||||
println("==================== accessOk ${accessOk} ======================")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
request.cookies.forEach {
|
|
||||||
if (it.name.equals("refresh", true) && jwtService.validateRefreshToken(access?.value, it.value)) {
|
|
||||||
refresh = it
|
|
||||||
refreshOk = true
|
|
||||||
println("==================== refreshOk ${refreshOk} ======================")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (refreshOk || accessOk) {
|
|
||||||
request.getSession(true)?.let { session ->
|
|
||||||
session.setAttribute(WRITE_PERMISSION_KEY, true)
|
|
||||||
session.maxInactiveInterval = 60 * 5
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (request.requestURI.contains("logout")) {
|
|
||||||
request.getSession(true)?.let { session ->
|
|
||||||
session.invalidate()
|
|
||||||
session.setAttribute(WRITE_PERMISSION_KEY, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request.cookies?.forEach {
|
|
||||||
if (it.name.equals("CLEAR", true)) {
|
|
||||||
request.getSession(false)?.let { session ->
|
|
||||||
// session.invalidate()
|
|
||||||
session.setAttribute(WRITE_PERMISSION_KEY, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
modelAndView?.modelMap?.put(WRITE_PERMISSION_KEY,"NO")
|
|
||||||
request.getSession(true)?.let {
|
|
||||||
(it.getAttribute(WRITE_PERMISSION_KEY) as? Boolean)?.let { permission ->
|
|
||||||
if (permission) {
|
|
||||||
modelAndView?.modelMap?.put(WRITE_PERMISSION_KEY,"OK")
|
|
||||||
modelAndView?.modelMap?.put(EncTypeKey, EncType11)
|
|
||||||
modelAndView?.modelMap?.put(ApiKeyWordKey,"Def")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println("==================== END ======================")
|
|
||||||
println("===============================================")
|
|
||||||
}
|
|
||||||
super.postHandle(request, response, handler, modelAndView)
|
super.postHandle(request, response, handler, modelAndView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,19 +18,19 @@ class GlobalEnvironment : EnvironmentAware {
|
|||||||
fun padding(key : String) = pad.plus(key).plus(pad)
|
fun padding(key : String) = pad.plus(key).plus(pad)
|
||||||
}
|
}
|
||||||
@Value("\${telegram.bot.key}")
|
@Value("\${telegram.bot.key}")
|
||||||
var telegramBotKey: String? = ""
|
lateinit var telegramBotKey: String
|
||||||
|
|
||||||
@Value("\${telegram.my.id}")
|
@Value("\${telegram.my.id}")
|
||||||
var telegramMyId: String? = ""
|
lateinit var telegramMyId: String
|
||||||
|
|
||||||
@Value("\${telegram.target.id}")
|
@Value("\${telegram.target.id}")
|
||||||
var telegramTargetId: String? = ""
|
lateinit var telegramTargetId: String
|
||||||
|
|
||||||
@Value("\${weather.api.key}")
|
@Value("\${weather.api.key}")
|
||||||
var weatherApiKey: String? = ""
|
lateinit var weatherApiKey: String
|
||||||
|
|
||||||
@Value("\${api.gg.place}")
|
@Value("\${api.gg.place}")
|
||||||
var gapiKey : String? = ""
|
lateinit var gapiKey: String
|
||||||
|
|
||||||
// @Value("jwt.access-secret")
|
// @Value("jwt.access-secret")
|
||||||
var ACCESS_SECRET_KEY: String = "l00u00n00a00t00i00c00b00u00m00a00c00sk"
|
var ACCESS_SECRET_KEY: String = "l00u00n00a00t00i00c00b00u00m00a00c00sk"
|
||||||
@ -42,6 +42,7 @@ class GlobalEnvironment : EnvironmentAware {
|
|||||||
var REFRESH_EXPIRATION: Long = 60 * 30 * 1000L
|
var REFRESH_EXPIRATION: Long = 60 * 30 * 1000L
|
||||||
|
|
||||||
override fun setEnvironment(environment: Environment) {
|
override fun setEnvironment(environment: Environment) {
|
||||||
|
environment.activeProfiles.forEach { println(it) }
|
||||||
println ("telegramBotKey $telegramBotKey")
|
println ("telegramBotKey $telegramBotKey")
|
||||||
println("telegramMyId $telegramMyId")
|
println("telegramMyId $telegramMyId")
|
||||||
println("telegramMyId $telegramTargetId")
|
println("telegramMyId $telegramTargetId")
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package kr.lunaticbum.back.lun.configs
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
|
import kr.lunaticbum.back.lun.model.UserManager
|
||||||
import kr.lunaticbum.back.lun.utils.LogService
|
import kr.lunaticbum.back.lun.utils.LogService
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
@ -11,6 +12,8 @@ import org.springframework.http.HttpMethod
|
|||||||
import org.springframework.http.HttpStatus
|
import org.springframework.http.HttpStatus
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.security.access.AccessDeniedException
|
import org.springframework.security.access.AccessDeniedException
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
|
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.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy
|
import org.springframework.security.config.http.SessionCreationPolicy
|
||||||
@ -24,60 +27,87 @@ import org.springframework.web.ErrorResponse
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
class SecurityConfig {
|
class SecurityConfig(
|
||||||
|
private val userManager: UserManager,
|
||||||
|
private val bCryptPasswordEncoder: BCryptPasswordEncoder
|
||||||
|
) {
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var logService: LogService
|
lateinit var logService: LogService
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
|
||||||
http.csrf {
|
http.csrf { csrf ->
|
||||||
it.ignoringRequestMatchers("/user/joinUser.ajax").disable()
|
csrf.ignoringRequestMatchers("/user/login.bjx", "/user/joinUser.bjx") // 여기 예외 추가
|
||||||
|
}.authorizeHttpRequests { auth ->
|
||||||
|
auth
|
||||||
|
.requestMatchers(
|
||||||
|
"/", "/home",
|
||||||
|
"/bums/where.bs" ,
|
||||||
|
"/user/login.bs", "/user/signup.bs","/user/login.bjx",
|
||||||
|
"/css/**", "/js/**", "/images/**", "/webjars/**", "/assets/**").permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
}.formLogin { form ->
|
||||||
|
form.loginPage("/user/login.bs")
|
||||||
|
.defaultSuccessUrl("/", true)
|
||||||
|
.permitAll()
|
||||||
|
}.rememberMe { rememberMe ->
|
||||||
|
rememberMe
|
||||||
|
.key("BsTs*!12@") // 보통 안전한 키 지정
|
||||||
|
.tokenValiditySeconds(60 * 60 * 24 * 7) // 7일간 유효
|
||||||
|
.userDetailsService(userManager) // 사용자 정보 서비스 지정
|
||||||
|
}.logout { logout ->
|
||||||
|
logout.logoutUrl("/user/logout.bs").logoutSuccessUrl("/").permitAll()
|
||||||
}
|
}
|
||||||
http.cors { it.disable() }
|
|
||||||
http.headers {
|
|
||||||
it.frameOptions { frameOptionsConfig ->
|
|
||||||
frameOptionsConfig.disable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
http.authorizeHttpRequests {
|
|
||||||
logService.log(it.toString())
|
|
||||||
it.requestMatchers(HttpMethod.POST,"/user/**").permitAll()
|
|
||||||
// it.requestMatchers(HttpMethod.POST,"/user/**").permitAll()
|
|
||||||
// it.requestMatchers(HttpMethod.POST,"/user/**").permitAll()
|
|
||||||
// it.requestMatchers("/", "/user/**").permitAll()
|
|
||||||
// .requestMatchers(".ajax").permitAll()
|
|
||||||
// it.requestMatchers("/", "/user/joinUser.api").permitAll()
|
|
||||||
// it.requestMatchers("user/joinUser.api").permitAll()
|
|
||||||
it.requestMatchers("/blog/viewer/**").permitAll()
|
|
||||||
it.anyRequest().permitAll()
|
|
||||||
|
|
||||||
// .requestMatchers("/", "/login/**").permitAll()
|
|
||||||
|
|
||||||
// .requestMatchers("/admins/**", "/api/v1/admins/**").hasRole(Role.ADMIN.name)
|
|
||||||
// .anyRequest().authenticated()
|
|
||||||
}
|
|
||||||
http.sessionManagement {
|
|
||||||
it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
||||||
}
|
|
||||||
.exceptionHandling { it ->
|
|
||||||
it.authenticationEntryPoint(unauthorizedEntryPoint)
|
|
||||||
.accessDeniedHandler(accessDeniedHandler)
|
|
||||||
}
|
|
||||||
// .formLogin { formLogin ->
|
|
||||||
// formLogin
|
|
||||||
// .loginPage("/user/join")
|
|
||||||
////// .usernameParameter("username")
|
|
||||||
////// .passwordParameter("password")
|
|
||||||
// .loginProcessingUrl("/user/joinUser.api")
|
|
||||||
// .defaultSuccessUrl("/", true)
|
|
||||||
// }
|
|
||||||
|
|
||||||
return http.build()
|
return http.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun authenticationManager(http: HttpSecurity): AuthenticationManager {
|
||||||
|
val authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder::class.java)
|
||||||
|
authenticationManagerBuilder
|
||||||
|
.userDetailsService(userManager)
|
||||||
|
.passwordEncoder(bCryptPasswordEncoder)
|
||||||
|
return authenticationManagerBuilder.build() // .and() 없이 직접 build() 호출
|
||||||
|
}
|
||||||
|
// @Bean
|
||||||
|
// fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
|
//
|
||||||
|
// http.csrf {
|
||||||
|
// it.ignoringRequestMatchers("/user/joinUser.bjx").disable()
|
||||||
|
// }
|
||||||
|
// http.cors { it.disable() }
|
||||||
|
// http.headers {
|
||||||
|
// it.frameOptions { frameOptionsConfig ->
|
||||||
|
// frameOptionsConfig.disable()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// http.authorizeHttpRequests {
|
||||||
|
// logService.log(it.toString())
|
||||||
|
// it.requestMatchers(HttpMethod.POST,"/user/**").permitAll()
|
||||||
|
// it.requestMatchers("/blog/viewer/**").permitAll()
|
||||||
|
// it.anyRequest().permitAll()
|
||||||
|
// }
|
||||||
|
// http.sessionManagement {
|
||||||
|
// it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
// }
|
||||||
|
// .exceptionHandling { it ->
|
||||||
|
// it.authenticationEntryPoint(unauthorizedEntryPoint)
|
||||||
|
// .accessDeniedHandler(accessDeniedHandler)
|
||||||
|
// }
|
||||||
|
//// .formLogin { formLogin ->
|
||||||
|
//// formLogin
|
||||||
|
//// .loginPage("/user/join")
|
||||||
|
//////// .usernameParameter("username")
|
||||||
|
//////// .passwordParameter("password")
|
||||||
|
//// .loginProcessingUrl("/user/joinUser.api")
|
||||||
|
//// .defaultSuccessUrl("/", true)
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// return http.build()
|
||||||
|
// }
|
||||||
|
|
||||||
private val unauthorizedEntryPoint =
|
private val unauthorizedEntryPoint =
|
||||||
AuthenticationEntryPoint { request: HttpServletRequest?, response: HttpServletResponse, authException: AuthenticationException? ->
|
AuthenticationEntryPoint { request: HttpServletRequest?, response: HttpServletResponse, authException: AuthenticationException? ->
|
||||||
val fail: ErrorResponse = ErrorResponse.create( Throwable("아직 못들어와"),
|
val fail: ErrorResponse = ErrorResponse.create( Throwable("아직 못들어와"),
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.ApiKeyWordKey
|
|||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
||||||
import kr.lunaticbum.back.lun.model.*
|
import kr.lunaticbum.back.lun.model.*
|
||||||
import kr.lunaticbum.back.lun.service.JwtService
|
|
||||||
import kr.lunaticbum.back.lun.utils.LogService
|
import kr.lunaticbum.back.lun.utils.LogService
|
||||||
import kr.lunaticbum.back.lun.utils.getFileExtension
|
import kr.lunaticbum.back.lun.utils.getFileExtension
|
||||||
import net.coobird.thumbnailator.Thumbnails
|
import net.coobird.thumbnailator.Thumbnails
|
||||||
@ -28,6 +27,8 @@ import org.springframework.core.io.Resource
|
|||||||
import org.springframework.core.io.UrlResource
|
import org.springframework.core.io.UrlResource
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import org.springframework.web.multipart.MultipartFile
|
import org.springframework.web.multipart.MultipartFile
|
||||||
import org.springframework.web.reactive.function.client.WebClient
|
import org.springframework.web.reactive.function.client.WebClient
|
||||||
@ -55,7 +56,7 @@ class BlogController() {
|
|||||||
@Autowired
|
@Autowired
|
||||||
lateinit var logService: LogService
|
lateinit var logService: LogService
|
||||||
val WRITE_PERMISSION_KEY = "PERMISSION"
|
val WRITE_PERMISSION_KEY = "PERMISSION"
|
||||||
@GetMapping("write/{token}","write")
|
@GetMapping("write/{token}","write.bs")
|
||||||
fun writ(@PathVariable token : String? ) : ResultMV{
|
fun writ(@PathVariable token : String? ) : ResultMV{
|
||||||
val vm = ResultMV("content/blog/write")
|
val vm = ResultMV("content/blog/write")
|
||||||
if (token.equals(TEMPTOKEN)) {
|
if (token.equals(TEMPTOKEN)) {
|
||||||
@ -67,17 +68,10 @@ class BlogController() {
|
|||||||
} else {
|
} else {
|
||||||
vm.modelMap.put(WRITE_PERMISSION_KEY,"NO")
|
vm.modelMap.put(WRITE_PERMISSION_KEY,"NO")
|
||||||
}
|
}
|
||||||
// when(System.currentTimeMillis() % 5L) {
|
|
||||||
// 0L -> vm.modelMap.put(EncTypeKey,"T4")
|
|
||||||
// 1L -> vm.modelMap.put(EncTypeKey,"T3")
|
|
||||||
// 2L -> vm.modelMap.put(EncTypeKey,"T2")
|
|
||||||
// else -> vm.modelMap.put(EncTypeKey,"T0")
|
|
||||||
// }
|
|
||||||
|
|
||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("post.ajax")
|
@PostMapping("post.bjx")
|
||||||
fun post(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
fun post(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
||||||
logService.log(httpServletRequest.requestURI)
|
logService.log(httpServletRequest.requestURI)
|
||||||
logService.log(jsonString)
|
logService.log(jsonString)
|
||||||
@ -164,16 +158,16 @@ class BlogController() {
|
|||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
|
||||||
lateinit var jwtService : JwtService
|
|
||||||
|
|
||||||
@GetMapping("modify")
|
@GetMapping("modify.bs")
|
||||||
fun modify(httpServletRequest: HttpServletRequest, @RequestParam("token") token : String?) : ResultMV{
|
fun modify(httpServletRequest: HttpServletRequest, @RequestParam("token") token : String?) : ResultMV{
|
||||||
logService.log("incoming modify")
|
logService.log("incoming modify")
|
||||||
val vm = ResultMV("content/blog/modify")
|
val vm = ResultMV("content/blog/modify")
|
||||||
vm.modelMap.put(WRITE_PERMISSION_KEY,"NO")
|
val authentication = SecurityContextHolder.getContext().authentication
|
||||||
httpServletRequest.getSession(true)?.let { session ->
|
val principal = authentication.principal
|
||||||
(session.getAttribute(WRITE_PERMISSION_KEY) as? Boolean)?.let {
|
if (principal is UserDetails) {
|
||||||
|
val username = principal.username
|
||||||
|
// 추가 정보 사용 가능
|
||||||
postManageg.find20()?.apply {
|
postManageg.find20()?.apply {
|
||||||
forEach {
|
forEach {
|
||||||
it.title = URLDecoder.decode(it.title)
|
it.title = URLDecoder.decode(it.title)
|
||||||
@ -186,7 +180,6 @@ class BlogController() {
|
|||||||
vm.modelMap.put("path","editor/")
|
vm.modelMap.put("path","editor/")
|
||||||
vm.modelMap.put("SK",token)
|
vm.modelMap.put("SK",token)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
vm.modelMap.put("rowKey","chunkedPosts_")
|
vm.modelMap.put("rowKey","chunkedPosts_")
|
||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ class BumsPrivate {
|
|||||||
@Autowired
|
@Autowired
|
||||||
lateinit var locationService: LocationLogService
|
lateinit var locationService: LocationLogService
|
||||||
|
|
||||||
@GetMapping("where")
|
@GetMapping("where.bs")
|
||||||
fun where() : ResultMV {
|
fun where() : ResultMV {
|
||||||
val m = ResultMV("content/private/where")
|
val m = ResultMV("content/private/where")
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncType11
|
|||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
import kr.lunaticbum.back.lun.configs.GlobalEnvironment.Companion.EncTypeKey
|
||||||
import kr.lunaticbum.back.lun.configs.JwtRule
|
import kr.lunaticbum.back.lun.configs.JwtRule
|
||||||
import kr.lunaticbum.back.lun.model.*
|
import kr.lunaticbum.back.lun.model.*
|
||||||
import kr.lunaticbum.back.lun.service.JwtService
|
|
||||||
import kr.lunaticbum.back.lun.utils.JwtUtil
|
import kr.lunaticbum.back.lun.utils.JwtUtil
|
||||||
import kr.lunaticbum.back.lun.utils.LogService
|
import kr.lunaticbum.back.lun.utils.LogService
|
||||||
import kr.lunaticbum.back.lun.utils.extractModelData
|
import kr.lunaticbum.back.lun.utils.extractModelData
|
||||||
@ -17,12 +16,18 @@ import org.springframework.beans.factory.annotation.Autowired
|
|||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.http.ResponseCookie
|
import org.springframework.http.ResponseCookie
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import org.springframework.web.reactive.function.client.WebClient
|
import org.springframework.web.reactive.function.client.WebClient
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
import org.springframework.security.web.authentication.RememberMeServices
|
||||||
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.naming.AuthenticationException
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@ -38,10 +43,8 @@ class UserController {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var userManager: UserManager
|
lateinit var userManager: UserManager
|
||||||
@Autowired
|
|
||||||
lateinit var jwtService : JwtService
|
|
||||||
|
|
||||||
@GetMapping("join")
|
@GetMapping("join.bs")
|
||||||
fun hello(httpServletRequest: HttpServletRequest): ResultMV {
|
fun hello(httpServletRequest: HttpServletRequest): ResultMV {
|
||||||
logService.log("onJoin")
|
logService.log("onJoin")
|
||||||
val vm = ResultMV("content/user/join")
|
val vm = ResultMV("content/user/join")
|
||||||
@ -60,7 +63,7 @@ class UserController {
|
|||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("login")
|
@GetMapping("login.bs")
|
||||||
fun userLogin(httpServletRequest: HttpServletRequest): ResultMV {
|
fun userLogin(httpServletRequest: HttpServletRequest): ResultMV {
|
||||||
logService.log("onJoin")
|
logService.log("onJoin")
|
||||||
val vm = ResultMV("content/user/login")
|
val vm = ResultMV("content/user/login")
|
||||||
@ -69,9 +72,18 @@ class UserController {
|
|||||||
return vm
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @GetMapping("logout.bs")
|
||||||
|
// fun logoutBs(session: HttpSession): ResultMV {
|
||||||
|
// session.invalidate(); // 세션 날리기 (로그아웃)
|
||||||
|
// return "redirect:/"; // 홈으로 이동
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
lateinit var authenticationManager: AuthenticationManager
|
||||||
|
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping("login.ajax")
|
@PostMapping("login.bjx")
|
||||||
fun login(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<LoginResult> {
|
fun login(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<LoginResult> {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@ -82,24 +94,37 @@ class UserController {
|
|||||||
var u : UserDetails? = null
|
var u : UserDetails? = null
|
||||||
var user : User? = null
|
var user : User? = null
|
||||||
var tokenData : TokenData? = null
|
var tokenData : TokenData? = null
|
||||||
|
var remeberMe = false
|
||||||
|
var authResult : Authentication? = null
|
||||||
jsonString.extractModelData { exception, originDataString ->
|
jsonString.extractModelData { exception, originDataString ->
|
||||||
if (exception == null) {
|
if (exception == null) {
|
||||||
logService.log(originDataString)
|
logService.log("originDataString >>> $originDataString")
|
||||||
val target = Gson().fromJson(originDataString, User::class.java) ?: User()
|
val target = Gson().fromJson(originDataString, User::class.java) ?: User()
|
||||||
user = userManager.findById(target.user_id?.trim() ?: "")?.block()
|
try {
|
||||||
if (user == null && ((target.user_id?.trim()?.length ?: 0) > 3 == true)) {
|
val authToken = UsernamePasswordAuthenticationToken(target.user_id, target.user_pw)
|
||||||
user = userManager.findByEmail(target.user_id?.trim() ?: "")?.block()
|
authResult = authenticationManager.authenticate(authToken) // 인증 시도
|
||||||
}
|
println("authResult >>>> $authResult")
|
||||||
if (user != null) {
|
// 인증 성공 시 SecurityContextHolder에 인증 정보 저장
|
||||||
if(userManager.isCorrectUser(user!!,target.user_pw!!)){
|
SecurityContextHolder.getContext().authentication = authResult
|
||||||
tokenData = jwtService.generate(user!!)
|
|
||||||
|
// 인증 정보가 담긴 SecurityContext를 세션에 저장
|
||||||
|
val session = httpServletRequest.getSession(true)
|
||||||
|
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext())
|
||||||
|
println("authResult >>>> LOGIN OK")
|
||||||
|
|
||||||
|
val principal = authResult?.principal
|
||||||
|
if (principal is UserDetails) {
|
||||||
|
val username = principal.username
|
||||||
|
|
||||||
|
val session = httpServletRequest.getSession(true)
|
||||||
|
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext())
|
||||||
|
remeberMe = target.remeberMe ?: false
|
||||||
} else {
|
} else {
|
||||||
lResultMsg = "is wrong infomation id or passord"
|
lResultMsg = "is wrong infomation id or passord"
|
||||||
lResultCode = 7100
|
lResultCode = 7100
|
||||||
}
|
}
|
||||||
} else {
|
} catch (e: Exception) {
|
||||||
lResultMsg = "not founding user[can't find same id,email.. ]"
|
e.printStackTrace()
|
||||||
lResultCode = 7100
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exception.printStackTrace()
|
exception.printStackTrace()
|
||||||
@ -117,7 +142,6 @@ class UserController {
|
|||||||
this.refresh = setTokenToCookie(JwtRule.REFRESH_PREFIX.value, tokenData?.refreshToken ?: "", globalEvv.REFRESH_EXPIRATION / 1000).toString().replace("refresh=","")
|
this.refresh = setTokenToCookie(JwtRule.REFRESH_PREFIX.value, tokenData?.refreshToken ?: "", globalEvv.REFRESH_EXPIRATION / 1000).toString().replace("refresh=","")
|
||||||
}).apply {
|
}).apply {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return responce
|
return responce
|
||||||
@ -149,7 +173,7 @@ class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping("logout.ajax")
|
@PostMapping("logout.bjx")
|
||||||
fun logout(httpServletRequest: HttpServletRequest) : ResponseEntity<ResponceResult> {
|
fun logout(httpServletRequest: HttpServletRequest) : ResponseEntity<ResponceResult> {
|
||||||
val responce = ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(ResponceResult().apply {
|
val responce = ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(ResponceResult().apply {
|
||||||
|
|
||||||
@ -158,7 +182,7 @@ class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping("joinUser.ajax")
|
@PostMapping("joinUser.bjx")
|
||||||
fun joinUser(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
fun joinUser(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
||||||
logService.log("${httpServletRequest.requestURI}")
|
logService.log("${httpServletRequest.requestURI}")
|
||||||
logService.log(jsonString)
|
logService.log(jsonString)
|
||||||
@ -174,9 +198,6 @@ class UserController {
|
|||||||
}else if (userManager.findById(user!!.user_id!!)?.block() != null) {
|
}else if (userManager.findById(user!!.user_id!!)?.block() != null) {
|
||||||
lResultCode = 7001
|
lResultCode = 7001
|
||||||
lResultMsg = "user insert Fail Reason : already has Same Id"
|
lResultMsg = "user insert Fail Reason : already has Same Id"
|
||||||
}else if (userManager.findByEmail(user!!.user_email!!)?.block() != null ) {
|
|
||||||
lResultCode = 7002
|
|
||||||
lResultMsg = "user insert Fail Reason : already has Same Email"
|
|
||||||
} else {
|
} else {
|
||||||
u = userManager.save(user).block()
|
u = userManager.save(user).block()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,10 +39,12 @@ class User {
|
|||||||
@CreatedDate
|
@CreatedDate
|
||||||
var user_join: Long = 0L
|
var user_join: Long = 0L
|
||||||
|
|
||||||
var user_name: String? = null
|
// var user_name: String? = null
|
||||||
var isAccept : String? = null
|
var isAccept : String? = null
|
||||||
var isAdmin : String? = null
|
var isAdmin : String? = null
|
||||||
|
|
||||||
|
var remeberMe : Boolean? = false
|
||||||
|
|
||||||
fun checkValid() : Boolean {
|
fun checkValid() : Boolean {
|
||||||
if (
|
if (
|
||||||
((user_id?.length ?: 0) > 5) &&
|
((user_id?.length ?: 0) > 5) &&
|
||||||
@ -111,8 +113,8 @@ interface UserRepository : ReactiveMongoRepository<User, String> {
|
|||||||
@Query("{user_id :?0}")
|
@Query("{user_id :?0}")
|
||||||
override fun findById(user_id: String): Mono<User>
|
override fun findById(user_id: String): Mono<User>
|
||||||
|
|
||||||
@Query("{user_email :?0}")
|
// @Query("{user_email :?0}")
|
||||||
fun findByEmail(user_email: String): Mono<User>
|
// fun findByEmail(user_email: String): Mono<User>
|
||||||
|
|
||||||
|
|
||||||
fun save(user: User): Mono<User>
|
fun save(user: User): Mono<User>
|
||||||
@ -123,23 +125,24 @@ enum class UserRole {
|
|||||||
}
|
}
|
||||||
interface UserService {
|
interface UserService {
|
||||||
fun findById(id: String): Mono<User>?
|
fun findById(id: String): Mono<User>?
|
||||||
fun findByEmail(id: String): Mono<User>?
|
// fun findByEmail(id: String): Mono<User>?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UserManager : UserService , UserDetailsService {
|
class UserManager(
|
||||||
|
private val passwordEncoder: PasswordEncoder
|
||||||
|
) : UserService , UserDetailsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private lateinit var logService: LogService
|
private lateinit var logService: LogService
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private lateinit var userRepository: UserRepository
|
private lateinit var userRepository: UserRepository
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private lateinit var bCryptPasswordEncoder: PasswordEncoder
|
|
||||||
|
|
||||||
override fun findByEmail(id: String): Mono<User>? {
|
|
||||||
return userRepository.findByEmail(id)
|
// override fun findByEmail(id: String): Mono<User>? {
|
||||||
}
|
// return userRepository.findByEmail(id)
|
||||||
|
// }
|
||||||
|
|
||||||
override fun findById(id: String): Mono<User>? {
|
override fun findById(id: String): Mono<User>? {
|
||||||
return userRepository.findById(id)
|
return userRepository.findById(id)
|
||||||
@ -149,19 +152,22 @@ class UserManager : UserService , UserDetailsService {
|
|||||||
|
|
||||||
fun save(user: User): Mono<User> {
|
fun save(user: User): Mono<User> {
|
||||||
println("saved user before ${user}")
|
println("saved user before ${user}")
|
||||||
user.hashPassword(bCryptPasswordEncoder)
|
user.hashPassword(passwordEncoder)
|
||||||
return userRepository.save(user)
|
return userRepository.save(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCorrectUser(user: User, password : String) : Boolean {
|
fun isCorrectUser(user: User, password : String) : Boolean {
|
||||||
return user.checkPassword(password,bCryptPasswordEncoder)
|
return user.checkPassword(password,passwordEncoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun loadUserByUsername(username: String?): UserDetails {
|
override fun loadUserByUsername(username: String?): UserDetails {
|
||||||
var user = findById(username!!)?.blockOptional(Duration.ofMillis(5000L))?.get() ?: User()
|
|
||||||
logService.log("username ${username}")
|
logService.log("username ${username}")
|
||||||
user.hashPassword(bCryptPasswordEncoder)
|
var user = findById(username!!)?.blockOptional(Duration.ofMillis(5000L))?.get() ?: User()
|
||||||
return org.springframework.security.core.userdetails.User.builder().username(user.user_id ?: "").password(user.user_pw).roles(if ("Y".equals(user.isAdmin)) Role.ADMIN.name else {Role.USER.name}).build()
|
// user.hashPassword(passwordEncoder)
|
||||||
|
return org.springframework.security.core.userdetails.User.builder()
|
||||||
|
.username(user.user_id ?: "")
|
||||||
|
.password(user.user_pw)
|
||||||
|
.roles(if ("Y".equals(user.isAdmin)) Role.ADMIN.name else {Role.USER.name}).build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,185 +1,185 @@
|
|||||||
package kr.lunaticbum.back.lun.service
|
//package kr.lunaticbum.back.lun.service
|
||||||
|
//
|
||||||
import io.jsonwebtoken.Claims
|
//import io.jsonwebtoken.Claims
|
||||||
import io.jsonwebtoken.Jws
|
//import io.jsonwebtoken.Jws
|
||||||
import io.jsonwebtoken.Jwts
|
//import io.jsonwebtoken.Jwts
|
||||||
import jakarta.servlet.http.Cookie
|
//import jakarta.servlet.http.Cookie
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
//import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
//import jakarta.servlet.http.HttpServletResponse
|
||||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment
|
//import kr.lunaticbum.back.lun.configs.GlobalEnvironment
|
||||||
import kr.lunaticbum.back.lun.configs.JwtGenerator
|
//import kr.lunaticbum.back.lun.configs.JwtGenerator
|
||||||
import kr.lunaticbum.back.lun.configs.JwtRule
|
//import kr.lunaticbum.back.lun.configs.JwtRule
|
||||||
import kr.lunaticbum.back.lun.configs.TokenStatus
|
//import kr.lunaticbum.back.lun.configs.TokenStatus
|
||||||
import kr.lunaticbum.back.lun.model.*
|
//import kr.lunaticbum.back.lun.model.*
|
||||||
import kr.lunaticbum.back.lun.utils.BusinessException
|
//import kr.lunaticbum.back.lun.utils.BusinessException
|
||||||
import kr.lunaticbum.back.lun.utils.ErrorCode
|
//import kr.lunaticbum.back.lun.utils.ErrorCode
|
||||||
import kr.lunaticbum.back.lun.utils.JwtUtil
|
//import kr.lunaticbum.back.lun.utils.JwtUtil
|
||||||
import lombok.extern.slf4j.Slf4j
|
//import lombok.extern.slf4j.Slf4j
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
//import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.http.HttpHeaders
|
//import org.springframework.http.HttpHeaders
|
||||||
import org.springframework.http.ResponseCookie
|
//import org.springframework.http.ResponseCookie
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.security.core.Authentication
|
//import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.core.token.Token
|
//import org.springframework.security.core.token.Token
|
||||||
import org.springframework.security.core.userdetails.UserDetails
|
//import org.springframework.security.core.userdetails.UserDetails
|
||||||
import org.springframework.stereotype.Service
|
//import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
//import org.springframework.transaction.annotation.Transactional
|
||||||
import java.security.Key
|
//import java.security.Key
|
||||||
import java.time.Duration
|
//import java.time.Duration
|
||||||
import java.util.*
|
//import java.util.*
|
||||||
import java.util.function.Consumer
|
//import java.util.function.Consumer
|
||||||
|
//
|
||||||
|
//
|
||||||
@Service
|
//@Service
|
||||||
@Transactional(readOnly = true)
|
//@Transactional(readOnly = true)
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
class JwtService {
|
//class JwtService {
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
lateinit var globalEvv : GlobalEnvironment
|
// lateinit var globalEvv : GlobalEnvironment
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
private lateinit var jwtGenerator: JwtGenerator
|
// private lateinit var jwtGenerator: JwtGenerator
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
private lateinit var jwtUtil: JwtUtil
|
// private lateinit var jwtUtil: JwtUtil
|
||||||
|
//
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
private lateinit var customUserDetailsService: UserManager
|
// private lateinit var customUserDetailsService: UserManager
|
||||||
|
//
|
||||||
@Autowired
|
// @Autowired
|
||||||
private lateinit var tokenRepository : TokenDataRepository
|
// private lateinit var tokenRepository : TokenDataRepository
|
||||||
|
//
|
||||||
// private val ACCESS_SECRET_KEY: Key = jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)
|
//// private val ACCESS_SECRET_KEY: Key = jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)
|
||||||
// private val REFRESH_SECRET_KEY: Key = jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY)
|
//// private val REFRESH_SECRET_KEY: Key = jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY)
|
||||||
|
//
|
||||||
fun validateUser(requestUser: User) {
|
// fun validateUser(requestUser: User) {
|
||||||
if (requestUser.getRole() === UserRole.NOT_REGISTERED) {
|
// if (requestUser.getRole() === UserRole.NOT_REGISTERED) {
|
||||||
throw BusinessException(ErrorCode.NOT_AUTHENTICATED_USER)
|
// throw BusinessException(ErrorCode.NOT_AUTHENTICATED_USER)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Transactional
|
// @Transactional
|
||||||
fun generate(requestUser: User): TokenData? {
|
// fun generate(requestUser: User): TokenData? {
|
||||||
var accessToken = jwtGenerator.generateAccessToken(jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY), globalEvv.ACCESS_EXPIRATION, requestUser)
|
// var accessToken = jwtGenerator.generateAccessToken(jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY), globalEvv.ACCESS_EXPIRATION, requestUser)
|
||||||
var refreshToken = jwtGenerator.generateRefreshToken(jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY), globalEvv.REFRESH_EXPIRATION, requestUser)
|
// var refreshToken = jwtGenerator.generateRefreshToken(jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY), globalEvv.REFRESH_EXPIRATION, requestUser)
|
||||||
var token = TokenData(accessToken, refreshToken)
|
// var token = TokenData(accessToken, refreshToken)
|
||||||
return tokenRepository.save(token).block()
|
// return tokenRepository.save(token).block()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
private fun setTokenToCookie(tokenPrefix: String, token: String, maxAgeSeconds: Long): ResponseCookie {
|
// private fun setTokenToCookie(tokenPrefix: String, token: String, maxAgeSeconds: Long): ResponseCookie {
|
||||||
return ResponseCookie.from(tokenPrefix, token)
|
// return ResponseCookie.from(tokenPrefix, token)
|
||||||
.path("/")
|
// .path("/")
|
||||||
.maxAge(maxAgeSeconds)
|
// .maxAge(maxAgeSeconds)
|
||||||
.httpOnly(true)
|
// .httpOnly(true)
|
||||||
.sameSite("None")
|
// .sameSite("None")
|
||||||
.secure(true)
|
// .secure(true)
|
||||||
.build()
|
// .build()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun validateAccessToken(token: String?): Boolean {
|
// fun validateAccessToken(token: String?): Boolean {
|
||||||
return jwtUtil.getTokenStatus(token, jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)) == TokenStatus.AUTHENTICATED
|
// return jwtUtil.getTokenStatus(token, jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)) == TokenStatus.AUTHENTICATED
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun validateRefreshToken(token: String?, refreshToken: String?): Boolean {
|
// fun validateRefreshToken(token: String?, refreshToken: String?): Boolean {
|
||||||
try {
|
// try {
|
||||||
val isRefreshValid = jwtUtil.getTokenStatus(refreshToken, jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY)) == TokenStatus.AUTHENTICATED
|
// val isRefreshValid = jwtUtil.getTokenStatus(refreshToken, jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY)) == TokenStatus.AUTHENTICATED
|
||||||
val storedToken: TokenData? = tokenRepository.findBytokenKey(token ?: "").block(Duration.ofSeconds(10))
|
// val storedToken: TokenData? = tokenRepository.findBytokenKey(token ?: "").block(Duration.ofSeconds(10))
|
||||||
val isTokenMatched: Boolean = storedToken?.refreshToken.equals(refreshToken)
|
// val isTokenMatched: Boolean = storedToken?.refreshToken.equals(refreshToken)
|
||||||
return isRefreshValid && isTokenMatched
|
// return isRefreshValid && isTokenMatched
|
||||||
} catch (e :Exception){
|
// } catch (e :Exception){
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
return false
|
// return false
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun resolveTokenFromCookie(request: HttpServletRequest, tokenPrefix: JwtRule?): String {
|
// fun resolveTokenFromCookie(request: HttpServletRequest, tokenPrefix: JwtRule?): String {
|
||||||
val cookies = request.cookies ?: throw BusinessException(ErrorCode.JWT_TOKEN_NOT_FOUND)
|
// val cookies = request.cookies ?: throw BusinessException(ErrorCode.JWT_TOKEN_NOT_FOUND)
|
||||||
return jwtUtil.resolveTokenFromCookie(cookies, tokenPrefix!!)
|
// return jwtUtil.resolveTokenFromCookie(cookies, tokenPrefix!!)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun getAuthentication(token: String): Authentication {
|
// fun getAuthentication(token: String): Authentication {
|
||||||
val principal: UserDetails = customUserDetailsService.loadUserByUsername(getUserPk(token, jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)))
|
// val principal: UserDetails = customUserDetailsService.loadUserByUsername(getUserPk(token, jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY)))
|
||||||
return UsernamePasswordAuthenticationToken(principal, "", principal.authorities)
|
// return UsernamePasswordAuthenticationToken(principal, "", principal.authorities)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun getUserPk(token: String, secretKey: Key): String {
|
// private fun getUserPk(token: String, secretKey: Key): String {
|
||||||
return Jwts.parserBuilder()
|
// return Jwts.parserBuilder()
|
||||||
.setSigningKey(secretKey)
|
// .setSigningKey(secretKey)
|
||||||
.build()
|
// .build()
|
||||||
.parseClaimsJws(token)
|
// .parseClaimsJws(token)
|
||||||
.getBody()
|
// .getBody()
|
||||||
.getSubject()
|
// .getSubject()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun getIdentifierFromRefresh(refreshToken: String?): String {
|
// fun getIdentifierFromRefresh(refreshToken: String?): String {
|
||||||
try {
|
// try {
|
||||||
return Jwts.parserBuilder()
|
// return Jwts.parserBuilder()
|
||||||
.setSigningKey(jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY))
|
// .setSigningKey(jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY))
|
||||||
.build()
|
// .build()
|
||||||
.parseClaimsJws(refreshToken)
|
// .parseClaimsJws(refreshToken)
|
||||||
.getBody()
|
// .getBody()
|
||||||
.getSubject()
|
// .getSubject()
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
throw BusinessException(ErrorCode.INVALID_JWT)
|
// throw BusinessException(ErrorCode.INVALID_JWT)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun logout(token: String, response: HttpServletResponse) {
|
// fun logout(token: String, response: HttpServletResponse) {
|
||||||
tokenRepository.deleteBytokenKey(token)
|
// tokenRepository.deleteBytokenKey(token)
|
||||||
|
//
|
||||||
val accessCookie = jwtUtil.resetToken(JwtRule.ACCESS_PREFIX)
|
// val accessCookie = jwtUtil.resetToken(JwtRule.ACCESS_PREFIX)
|
||||||
val refreshCookie = jwtUtil.resetToken(JwtRule.REFRESH_PREFIX)
|
// val refreshCookie = jwtUtil.resetToken(JwtRule.REFRESH_PREFIX)
|
||||||
|
//
|
||||||
response.addCookie(accessCookie)
|
// response.addCookie(accessCookie)
|
||||||
response.addCookie(refreshCookie)
|
// response.addCookie(refreshCookie)
|
||||||
}
|
// }
|
||||||
fun getUserIdFromToken(token: String?): String? {
|
// fun getUserIdFromToken(token: String?): String? {
|
||||||
try {
|
// try {
|
||||||
return jwtUtil.extractToken(token,jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY))?.body?.get("Identifier")
|
// return jwtUtil.extractToken(token,jwtUtil.getSigningKey(globalEvv.ACCESS_SECRET_KEY))?.body?.get("Identifier")
|
||||||
.toString()
|
// .toString()
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
return null
|
// return null
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
fun getUserIdFromRefresh(token: String?): String? {
|
// fun getUserIdFromRefresh(token: String?): String? {
|
||||||
try {
|
// try {
|
||||||
return jwtUtil.extractToken(token,jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY))?.body?.get("Identifier")
|
// return jwtUtil.extractToken(token,jwtUtil.getSigningKey(globalEvv.REFRESH_SECRET_KEY))?.body?.get("Identifier")
|
||||||
.toString()
|
// .toString()
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
return null
|
// return null
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
fun hasPerrmission(request: HttpServletRequest): Boolean {
|
// fun hasPerrmission(request: HttpServletRequest): Boolean {
|
||||||
var correctUserCheck = -1;
|
// var correctUserCheck = -1;
|
||||||
if (request.requestURI.contains("logout") == false && !request.cookies.isNullOrEmpty() && request.cookies.filter { it.name.equals("access") && it.value.length > 0 }.size > 0) {
|
// if (request.requestURI.contains("logout") == false && !request.cookies.isNullOrEmpty() && request.cookies.filter { it.name.equals("access") && it.value.length > 0 }.size > 0) {
|
||||||
var access : Cookie?= null
|
// var access : Cookie?= null
|
||||||
var refresh : Cookie?= null
|
// var refresh : Cookie?= null
|
||||||
request.cookies.forEach {
|
// request.cookies.forEach {
|
||||||
if (it.name.equals("access", true) && validateAccessToken(it.value)){
|
// if (it.name.equals("access", true) && validateAccessToken(it.value)){
|
||||||
access = it
|
// access = it
|
||||||
correctUserCheck += 1
|
// correctUserCheck += 1
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
request.cookies.forEach {
|
// request.cookies.forEach {
|
||||||
if (it.name.equals("refresh", true) && validateRefreshToken(access?.value,it.value)){
|
// if (it.name.equals("refresh", true) && validateRefreshToken(access?.value,it.value)){
|
||||||
refresh = it
|
// refresh = it
|
||||||
correctUserCheck += 1
|
// correctUserCheck += 1
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if (correctUserCheck > 0) {
|
// if (correctUserCheck > 0) {
|
||||||
println("Response correctUserCheck ===> ${correctUserCheck}")
|
// println("Response correctUserCheck ===> ${correctUserCheck}")
|
||||||
} else {
|
// } else {
|
||||||
println("Response correctUserCheck ===> ${correctUserCheck}")
|
// println("Response correctUserCheck ===> ${correctUserCheck}")
|
||||||
}
|
// }
|
||||||
} else if (request.requestURI.contains("logout")) {
|
// } else if (request.requestURI.contains("logout")) {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
return correctUserCheck > 0
|
// return correctUserCheck > 0
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@ -65,6 +65,7 @@ fun String.extractModelData(calback : (Exception?,String)->Unit) {
|
|||||||
Gson().fromJson<RequestModel>(resultString, RequestModel::class.java).let { model ->
|
Gson().fromJson<RequestModel>(resultString, RequestModel::class.java).let { model ->
|
||||||
model.data?.let { jsonString ->
|
model.data?.let { jsonString ->
|
||||||
try {
|
try {
|
||||||
|
println("RequestModel ${jsonString}")
|
||||||
calback.invoke(null,model.extractData())
|
calback.invoke(null,model.extractData())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
calback.invoke(ExtractDataRequestModelException("Exception on extractData with ${Gson().toJson(model)}", e.cause), jsonString)
|
calback.invoke(ExtractDataRequestModelException("Exception on extractData with ${Gson().toJson(model)}", e.cause), jsonString)
|
||||||
|
|||||||
@ -86,6 +86,8 @@ spring.ai.vectorstore.qdrant.collection-name=blama_vectors
|
|||||||
|
|
||||||
spring.ai.ollama.embedding.enabled=true
|
spring.ai.ollama.embedding.enabled=true
|
||||||
|
|
||||||
|
resource.handler=.
|
||||||
|
resource.location=.
|
||||||
|
server.forward-headers-strategy=framework
|
||||||
#>>>>>>> ab915d0a416c69708f1df1ad76d7a14c779c1f59
|
#>>>>>>> ab915d0a416c69708f1df1ad76d7a14c779c1f59
|
||||||
|
|
||||||
|
|||||||
@ -168,3 +168,31 @@ footer {
|
|||||||
min-height: 5vh;
|
min-height: 5vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#rememberMe {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: lightblue; /* 체크박스 배경색 */
|
||||||
|
border: 2px solid blue; /* 테두리 색 */
|
||||||
|
appearance: none; /* 기본 OS 스타일 제거 */
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rememberMe:checked {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rememberMe:checked::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
left: 7px;
|
||||||
|
width: 5px;
|
||||||
|
height: 10px;
|
||||||
|
border: solid white;
|
||||||
|
border-width: 0 2px 2px 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
@ -31,7 +31,7 @@ function onclickWrite(type, keyword, html) {
|
|||||||
baseData.firstPostLat = encodeURIComponent(currentLat)
|
baseData.firstPostLat = encodeURIComponent(currentLat)
|
||||||
baseData.firstPostLon = encodeURIComponent(currentLon)
|
baseData.firstPostLon = encodeURIComponent(currentLon)
|
||||||
}
|
}
|
||||||
let uploadUrl = getMainPath() + "/blog/post.ajax";
|
let uploadUrl = getMainPath() + "/blog/post.bjx";
|
||||||
if(confirm(JSON.stringify(baseData) + "\n해당 내용으로\n유저 등록 하실??")) {
|
if(confirm(JSON.stringify(baseData) + "\n해당 내용으로\n유저 등록 하실??")) {
|
||||||
post(uploadUrl,type,JSON.stringify(baseData),keyword, function (resultData) {
|
post(uploadUrl,type,JSON.stringify(baseData),keyword, function (resultData) {
|
||||||
alert(resultData)
|
alert(resultData)
|
||||||
|
|||||||
@ -147,7 +147,7 @@ function postLogin(target,type, data, key,callBackResult) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
httpRequest.withCredentials = true
|
||||||
httpRequest.open('POST', target, true);
|
httpRequest.open('POST', target, true);
|
||||||
httpRequest.setRequestHeader("Content-Type", "text/plain");
|
httpRequest.setRequestHeader("Content-Type", "text/plain");
|
||||||
var odd = []
|
var odd = []
|
||||||
@ -172,15 +172,15 @@ function mainPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function gotoWrite() {
|
function gotoWrite() {
|
||||||
document.location.replace(getMainPath()+"/blog/write")
|
document.location.replace(getMainPath()+"/blog/write.bs")
|
||||||
}
|
}
|
||||||
|
|
||||||
function gotoModify() {
|
function gotoModify() {
|
||||||
document.location.replace(getMainPath()+"/blog/modify")
|
document.location.replace(getMainPath()+"/blog/modify.bs")
|
||||||
}
|
}
|
||||||
|
|
||||||
function gotoWhere() {
|
function gotoWhere() {
|
||||||
document.location.replace(getMainPath()+"/bums/where")
|
document.location.replace(getMainPath()+"/bums/where.bs")
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
@ -191,21 +191,35 @@ function logout() {
|
|||||||
console.log(document.cookie["JSESSIONID"])
|
console.log(document.cookie["JSESSIONID"])
|
||||||
document.cookie = "JSESSIONID=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
document.cookie = "JSESSIONID=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||||
document.cookie = "CLEAR="+Date.now()+"";
|
document.cookie = "CLEAR="+Date.now()+"";
|
||||||
let logOutUrl = getMainPath() + "/user/logout.ajax";
|
let logOutUrl = getMainPath() + "/user/logout.bs";
|
||||||
post(logOutUrl,"","","", function (resultData) {
|
|
||||||
alert("로그아웃 됨요~! 빠염~!")
|
|
||||||
document.location.replace(document.location)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
alert("로그아웃 됨요~! 빠염~!")
|
||||||
|
|
||||||
|
// 동적으로 form 생성하여 POST 요청 전송
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'POST';
|
||||||
|
form.action = getMainPath() + '/user/logout.bs';
|
||||||
|
|
||||||
|
// CSRF 토큰을 meta태그 등에서 얻어서 삽입 (예: <meta name="_csrf" content="토큰값">)
|
||||||
|
const csrfToken = document.querySelector('meta[name="_csrf"]').getAttribute('content');
|
||||||
|
const csrfParam = document.querySelector('meta[name="_csrf_parameter"]').getAttribute('content');
|
||||||
|
const csrfInput = document.createElement('input');
|
||||||
|
csrfInput.type = 'hidden';
|
||||||
|
csrfInput.name = csrfParam; // 예: "_csrf"
|
||||||
|
csrfInput.value = csrfToken;
|
||||||
|
form.appendChild(csrfInput);
|
||||||
|
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
function gotoLogin() {
|
function gotoLogin() {
|
||||||
console.log(`location.port >> ${location.port}`)
|
console.log(`location.port >> ${location.port}`)
|
||||||
location.href = getMainPath()+"/login"
|
location.href = getMainPath()+"/login.bs"
|
||||||
}
|
}
|
||||||
|
|
||||||
function gotoJoin() {
|
function gotoJoin() {
|
||||||
document.location.replace(getMainPath() + "/user/join")
|
document.location.replace(getMainPath() + "/user/join.bs")
|
||||||
}
|
}
|
||||||
|
|
||||||
function goToView(path,id) {
|
function goToView(path,id) {
|
||||||
@ -218,7 +232,7 @@ function onclickLogin(type, keyword) {
|
|||||||
'user_id': user_id.value,
|
'user_id': user_id.value,
|
||||||
'user_pw': user_pw.value,
|
'user_pw': user_pw.value,
|
||||||
}
|
}
|
||||||
postLogin(getMainPath()+"/user/login.ajax",type,JSON.stringify(data),keyword, function (data) {
|
postLogin(getMainPath()+"/user/login.bjx",type,JSON.stringify(data),keyword, function (data) {
|
||||||
if (data.isOk) {
|
if (data.isOk) {
|
||||||
|
|
||||||
document.cookie = "access=" + data.token.split(";")[0]+";"
|
document.cookie = "access=" + data.token.split(";")[0]+";"
|
||||||
@ -229,7 +243,7 @@ function onclickLogin(type, keyword) {
|
|||||||
} else {
|
} else {
|
||||||
if (data.resultCode === 7100) {
|
if (data.resultCode === 7100) {
|
||||||
if(confirm(`너 누구임 정보 없는데?!\n${data.resultMsg}[${data.resultCode}]\n가입 할래!?`)){
|
if(confirm(`너 누구임 정보 없는데?!\n${data.resultMsg}[${data.resultCode}]\n가입 할래!?`)){
|
||||||
document.location.replace(getMainPath() + "/user/join")
|
document.location.replace(getMainPath() + "/user/join.bs")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert(`너 누구임?!\n${data.resultMsg}[${data.resultCode}]`)
|
alert(`너 누구임?!\n${data.resultMsg}[${data.resultCode}]`)
|
||||||
@ -320,11 +334,13 @@ function submitLoginForm() {
|
|||||||
// const password = document.getElementById('loginPassword').value;
|
// const password = document.getElementById('loginPassword').value;
|
||||||
let user_id = document.getElementById('loginId')
|
let user_id = document.getElementById('loginId')
|
||||||
let user_pw = document.getElementById('loginPassword')
|
let user_pw = document.getElementById('loginPassword')
|
||||||
|
let rememberMe = document.getElementById('rememberMe')
|
||||||
let data = {
|
let data = {
|
||||||
'user_id': user_id.value,
|
'user_id': user_id.value,
|
||||||
'user_pw': user_pw.value,
|
'user_pw': user_pw.value,
|
||||||
|
'rememberMe' : rememberMe.value,
|
||||||
}
|
}
|
||||||
postLogin(getMainPath()+"/user/login.ajax",user_pw.data,JSON.stringify(data),user_pw.data, function (data) {
|
postLogin(getMainPath()+"/user/login.bjx",user_pw.data,JSON.stringify(data),user_pw.data, function (data) {
|
||||||
closePopup()
|
closePopup()
|
||||||
if (data.isOk) {
|
if (data.isOk) {
|
||||||
document.cookie = "access=" + data.token.split(";")[0]+";"
|
document.cookie = "access=" + data.token.split(";")[0]+";"
|
||||||
|
|||||||
@ -62,7 +62,7 @@ function onclickJoin(type, keyword) {
|
|||||||
}
|
}
|
||||||
if (user_pw.value === user_pw_check.value) {
|
if (user_pw.value === user_pw_check.value) {
|
||||||
if(confirm(JSON.stringify(data) + "\n해당 내용으로\n유저 등록 하실??")) {
|
if(confirm(JSON.stringify(data) + "\n해당 내용으로\n유저 등록 하실??")) {
|
||||||
post("joinUser.ajax",type,JSON.stringify(data),keyword, function (resultData) {
|
post("joinUser.bjx",type,JSON.stringify(data),keyword, function (resultData) {
|
||||||
alert(resultData)
|
alert(resultData)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
|
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head" id="head">
|
<th:block layout:fragment="head" id="head">
|
||||||
@ -86,10 +88,10 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="wrapper style2">
|
<section class="wrapper style2">
|
||||||
<th:block th:if="${PERMISSION != 'OK'}">
|
<th:block sec:authorize="isAnonymous()">
|
||||||
<h1>권한이 없는 뎁쇼?!</h1>
|
<h1>권한이 없는 뎁쇼?!</h1>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:if="${PERMISSION == 'OK'}">
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
<div id="editor" ></div>
|
<div id="editor" ></div>
|
||||||
<div class="write_controllbox">
|
<div class="write_controllbox">
|
||||||
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
|
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
@ -33,10 +34,10 @@
|
|||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
<div id="main_layer">
|
<div id="main_layer">
|
||||||
<th:block th:if="${PERMISSION != 'OK'}">
|
<th:block sec:authorize="isAnonymous()">
|
||||||
<h1>권한이 없는 뎁쇼?!</h1>
|
<h1>권한이 없는 뎁쇼?!</h1>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:if="${PERMISSION == 'OK'}">
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
<div class="post_layer">
|
<div class="post_layer">
|
||||||
<th:block class="posts_layer" id="posts" th:each="posts ,postsStat: ${chunkedPosts}">
|
<th:block class="posts_layer" id="posts" th:each="posts ,postsStat: ${chunkedPosts}">
|
||||||
<th:block class="posts_layer" th:class="${#strings.append(rowKey,postsStat.index)}" th:each="post, postStast : ${posts}">
|
<th:block class="posts_layer" th:class="${#strings.append(rowKey,postsStat.index)}" th:each="post, postStast : ${posts}">
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
@ -38,13 +39,13 @@
|
|||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
<section class="wrapper style2">
|
<section class="wrapper style2">
|
||||||
|
|
||||||
<div class="container" th:if="${PERMISSION == 'OK'}" onclick="loadEditor()">
|
<div class="container" sec:authorize="isAuthenticated()" onclick="loadEditor()">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
||||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
<div class="container" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
|
<div class="container" sec:authorize="isAnonymous()" onclick="openLoginPopup('login')">
|
||||||
<header class="major">
|
<header class="major">
|
||||||
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
||||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head" id="head">
|
<th:block layout:fragment="head" id="head">
|
||||||
@ -100,10 +101,10 @@
|
|||||||
</th:block>
|
</th:block>
|
||||||
<th:block layout:fragment="content" id="content">
|
<th:block layout:fragment="content" id="content">
|
||||||
<div id="main_layer">
|
<div id="main_layer">
|
||||||
<th:block th:if="${PERMISSION != 'OK'}">
|
<th:block sec:authorize="isAnonymous()">
|
||||||
<h1>권한이 없는 뎁쇼?!</h1>
|
<h1>권한이 없는 뎁쇼?!</h1>
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:if="${PERMISSION == 'OK'}">
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
<div class="layer">
|
<div class="layer">
|
||||||
<input id="title_field" class="write_option" />
|
<input id="title_field" class="write_option" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
@ -10,7 +11,7 @@
|
|||||||
<script type="text/javascript" th:src="@{/js/test.js}"></script>
|
<script type="text/javascript" th:src="@{/js/test.js}"></script>
|
||||||
<link th:href="@{/css/toast-ui-dark.css}" rel="stylesheet" />
|
<link th:href="@{/css/toast-ui-dark.css}" rel="stylesheet" />
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
document.addEventListener("DOMContentLoaded", onLoaded);
|
// document.addEventListener("DOMContentLoaded", onLoaded);
|
||||||
function goToViewer(item) {
|
function goToViewer(item) {
|
||||||
let uploadUrl = getMainPath() + "/blog/viewer/"+item.attributes['data'].value;
|
let uploadUrl = getMainPath() + "/blog/viewer/"+item.attributes['data'].value;
|
||||||
location.href = uploadUrl
|
location.href = uploadUrl
|
||||||
@ -73,12 +74,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="col-4 col-12-narrower">
|
<section class="col-4 col-12-narrower">
|
||||||
<div class="box highlight" th:if="${PERMISSION == 'OK'}" onclick=gotoWrite()>
|
<div class="box highlight" sec:authorize="isAuthenticated()" onclick=gotoWrite()>
|
||||||
<i class="icon solid major fa-pencil-alt"></i>
|
<i class="icon solid major fa-pencil-alt"></i>
|
||||||
<h3>글쓰기[Writing]</h3>
|
<h3>글쓰기[Writing]</h3>
|
||||||
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="box highlight" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
|
<div class="box highlight" sec:authorize="isAnonymous()" onclick="openLoginPopup('login')">
|
||||||
<i class="icon solid major fa-pencil-alt"></i>
|
<i class="icon solid major fa-pencil-alt"></i>
|
||||||
<h3>글쓰기[Writing]</h3>
|
<h3>글쓰기[Writing]</h3>
|
||||||
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
|
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<link th:href="@{/css/private.css}" rel="stylesheet" />
|
<link th:href="@{/css/private.css}" rel="stylesheet" />
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
<th:block layout:fragment="head">
|
<th:block layout:fragment="head">
|
||||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}"
|
layout:decorate="~{layout/default_layout}"
|
||||||
>
|
>
|
||||||
<th:block layout:fragment="head" id="head">
|
<th:block layout:fragment="head" id="head">
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
layout:decorate="~{layout/default_layout}">
|
layout:decorate="~{layout/default_layout}">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@ -1,39 +1,54 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
|
<html
|
||||||
|
xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
<th:block th:fragment="header">
|
<th:block th:fragment="header">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
|
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<h1><a th:href="@{/}" id="logo">BUM ' <em>sPace</em></a></h1>
|
<h1><a th:href="@{/}" id="logo">BUM ' <em>sPace</em></a></h1>
|
||||||
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
|
<span style="margin-left:20px;">환영합니다, <b sec:authentication="name"></b>님!</span>
|
||||||
|
</th:block>
|
||||||
<!-- Nav -->
|
<!-- Nav -->
|
||||||
<nav id="nav">
|
<nav id="nav">
|
||||||
<ul>
|
<ul>
|
||||||
<li id="menu_home" ><a th:href="@{/}">Home</a></li>
|
<li id="menu_home" ><a th:href="@{/}">Home</a></li>
|
||||||
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
|
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
|
||||||
|
|
||||||
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
|
<!-- <li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>-->
|
||||||
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
|
<!-- <li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>-->
|
||||||
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
|
<!-- <li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>-->
|
||||||
<li id="menu_drop">
|
<li id="menu_drop">
|
||||||
<a href="#">About</a>
|
<a href="#">About</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#">Lorem dolor</a></li>
|
<li><a href="javascript:gotoWhere()">bums's where</a></li>
|
||||||
<li><a href="#">Magna phasellus</a></li>
|
<li><a href="#">Magna phasellus</a></li>
|
||||||
<li><a href="#">Etiam sed tempus</a></li>
|
<li><a href="#">Etiam sed tempus</a></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#">Submenu</a>
|
<a href="#">Submenu</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#">Lorem dolor</a></li>
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
|
<li><a href="javascript:gotoWrite()">글쓰기</a></li>
|
||||||
|
<li><a href="javascript:gotoModify()">수정하기</a></li>
|
||||||
|
</th:block>
|
||||||
<li><a href="#">Phasellus magna</a></li>
|
<li><a href="#">Phasellus magna</a></li>
|
||||||
<li><a href="#">Magna phasellus</a></li>
|
<!-- <li><a href="#">Magna phasellus</a></li>-->
|
||||||
<li><a href="#">Etiam nisl</a></li>
|
<!-- <li><a href="#">Etiam nisl</a></li>-->
|
||||||
<li><a href="#">Veroeros feugiat</a></li>
|
<!-- <li><a href="#">Veroeros feugiat</a></li>-->
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a th:href="@{/licenses}">Licenses</a></li>
|
<li><a th:href="@{/licenses}">Licenses</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<th:block sec:authorize="!isAuthenticated()">
|
||||||
|
<li id="menu_login" ><a href="javascript:openLoginPopup('login')">LOGIN</a></li>
|
||||||
|
</th:block>
|
||||||
|
<th:block sec:authorize="isAuthenticated()">
|
||||||
|
<li>
|
||||||
|
<a href="javascript:logout()" style="margin-left:10px;">로그아웃</a>
|
||||||
|
<li>
|
||||||
|
</th:block>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@ -13,5 +13,7 @@
|
|||||||
<link rel="stylesheet" href="assets/css/main.css" />
|
<link rel="stylesheet" href="assets/css/main.css" />
|
||||||
<script async th:src="@{https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9504446465764716}" crossorigin="anonymous"></script>
|
<script async th:src="@{https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9504446465764716}" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" th:src="@{/js/common.js}"></script>
|
<script type="text/javascript" th:src="@{/js/common.js}"></script>
|
||||||
|
<meta name="_csrf" th:content="${_csrf.token}"/>
|
||||||
|
<meta name="_csrf_parameter" th:content="${_csrf.parameterName}"/>
|
||||||
</th:block>
|
</th:block>
|
||||||
</html>
|
</html>
|
||||||
@ -2,6 +2,7 @@
|
|||||||
<html lagn="ko"
|
<html lagn="ko"
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||||
xmlns="http://www.w3.org/1999/html">
|
xmlns="http://www.w3.org/1999/html">
|
||||||
<head>
|
<head>
|
||||||
<base th:href="@{/}" />
|
<base th:href="@{/}" />
|
||||||
@ -20,12 +21,47 @@
|
|||||||
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
|
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
|
||||||
</div>
|
</div>
|
||||||
<div id="overlay" class="login_overlay">
|
<div id="overlay" class="login_overlay">
|
||||||
|
<style>
|
||||||
|
.custom-checkbox {
|
||||||
|
display: none; /* 실제 체크박스 숨김 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #555;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox:checked + .custom-label {
|
||||||
|
background-color: #007bff;
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox:checked + .custom-label::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
left: 7px;
|
||||||
|
width: 5px;
|
||||||
|
height: 10px;
|
||||||
|
border: solid white;
|
||||||
|
border-width: 0 2px 2px 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div id="popup" class="login_popup">
|
<div id="popup" class="login_popup">
|
||||||
<div id="loginForm" class="login_form">
|
<div id="loginForm" class="login_form">
|
||||||
<h2>로그인</h2>
|
<h2>로그인</h2>
|
||||||
<form id="loginFormElement" onsubmit="return false;">
|
<form id="loginFormElement" onsubmit="return false;">
|
||||||
<input type="text" th:data="${enc}" id="loginId" placeholder="아이디" required>
|
<input type="text" th:data="${enc}" id="loginId" placeholder="아이디" required/>
|
||||||
<input type="password" th:data="${type}" id="loginPassword" placeholder="비밀번호" required>
|
<input type="password" th:data="${type}" id="loginPassword" placeholder="비밀번호" required/>
|
||||||
|
<input type="checkbox" id="rememberMe" class="custom-checkbox"/>
|
||||||
|
<label for="rememberMe" class="custom-label"></label>
|
||||||
|
<span>자동로그인</span>
|
||||||
<button type="submit" class="button">로그인</button>
|
<button type="submit" class="button">로그인</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user