Spring Security, 로그인 처리 완료

main
semin.baek 6 months ago
parent 2fc4fa18cf
commit b1bea58188

@ -1,24 +1,22 @@
<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import Login from './views/LoginView.vue'
import { RouterLink, RouterView, useRouter } from 'vue-router'
import { onMounted } from 'vue'
import { userApi } from '@/components/userInfo'
const router = useRouter()
onMounted(() => {
userApi.loginCheck().then(() => {
if (userInfo.isLogin) {
router.push('/main.html')
} else {
router.replace('/login.html')
}
})
})
</script>
<template>
<!--
<header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
<div class="wrapper">
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
<RouterLink to="/login">Login</RouterLink>
<RouterLink to="/main">Main</RouterLink>
</nav>
</div>
</header>
-->
<RouterView class="flex-fill" />
<footer class="w-100 border-top d-flex">
<div class="bg-info-subtle p-2 d-flex align-items-center w-100 bg-purple">바닥글(저작권, 링크 ) 영역</div>

@ -9,40 +9,42 @@ const userInfo = reactive({
export const userApi = {
loginProcess: async function (inputUsername, inputUserPassword) {
const data = { username: inputUsername, password: inputUserPassword }
axios.post('/public-api/loginProcess', data).then((response) => {
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = true
userInfo.userId = response.data.username
return true
} else {
return false
}
})
const response = await axios.post('/public-api/loginProcess', data, { withCredentials: true })
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = true
userInfo.userId = response.data.username
return true
} else {
return false
}
},
logoutProcess: async function () {
axios.post('/public-api/logoutProcess').then((response) => {
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = false
userInfo.userId = ''
return true
} else {
return false
}
})
const response = await axios.post('/public-api/logoutProcess')
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = false
userInfo.userId = ''
return true
} else {
return false
}
},
loginCheck: async function () {
axios.get('/public-api/sessionCheck').then((response) => {
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = true
userInfo.userId = response.data.username
return true
} else {
userInfo.isLogin = false
userInfo.userId = ''
return false
}
})
const response = await axios.get('/public-api/sessionCheck', { withCredentials: true })
if (response.status == 200 && response.data && response.data.success == true) {
userInfo.isLogin = true
userInfo.userId = response.data.username
return true
} else {
userInfo.isLogin = false
userInfo.userId = ''
return false
}
},
getEncryptText: async function (plainText) {
const response = await axios.post('/public-api/passwordGenerator', { password: plainText })
return response.data.password
},
}
window.userApi = userApi
window.userInfo = userInfo
export default userInfo

@ -1,5 +1,6 @@
<script setup>
import { reactive } from 'vue'
import { onMounted, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { userApi } from '@/components/userInfo'
const loginForm = reactive({
@ -7,6 +8,8 @@ const loginForm = reactive({
password: '',
})
const router = useRouter()
async function loginProcess() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(loginForm.username)) {
@ -22,8 +25,15 @@ async function loginProcess() {
alert('사용자 아이디 또는 비밀번호가 일치하지 않습니다.')
document.getElementById('floatingPassword').focus()
return
} else {
router.push('/main.html')
}
}
async function loginCheck() {
let isLogin = await userApi.loginCheck()
alert(isLogin)
}
</script>
<template>
@ -32,18 +42,19 @@ async function loginProcess() {
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com" :value="loginForm.username" />
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com" v-model="loginForm.username" />
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" :value="loginForm.password" @keydown.enter="loginProcess" />
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" v-model="loginForm.password" @keydown.enter="loginProcess" />
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
<label> <input type="checkbox" value="remember-me" /> Remember me </label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit" @submit="loginProcess">Sign in</button>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
<button class="w-100 btn btn-lg btn-primary" type="button" @click="loginCheck">login check</button>
<p class="mt-5 mb-3 text-muted">&copy; 20172021</p>
</form>
</main>

@ -7,11 +7,7 @@ import mkcert from 'vite-plugin-mkcert'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
mkcert({ certFileName: 'bsm-lab.dev.pem', keyFileName: 'bsm-lab.dev-key.pem' }),
],
plugins: [vue(), vueDevTools(), mkcert({ certFileName: 'bsm-lab.dev.pem', keyFileName: 'bsm-lab.dev-key.pem' })],
server: {
port: 443,
host: 'bsm-lab.dev',
@ -23,6 +19,13 @@ export default defineConfig({
secure: false,
ws: true,
},
'/public-api/': {
target: 'https://bsm-lab.dev:9443/public-api/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/public-api/, ''),
secure: false,
ws: true,
},
},
},
base: '/',

@ -2,8 +2,10 @@ package com.bsmlab.dfx.dfxconsole.framework.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
@ -11,7 +13,10 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import java.io.IOException;
import java.util.HashMap;
@ -40,14 +45,20 @@ public class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAu
// 로그인 성공 후 결과 메시지 전달. 자동 호출됨.
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException {
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
log.info("로그인 성공: {}", authResult.getName());
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(authResult);
SecurityContextHolder.setContext(securityContext);
HttpSession httpSession = request.getSession(true);
httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext);
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/json");
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("username", authResult.getName());
objectMapper.writeValue(response.getWriter(), result);
chain.doFilter(request, response);
}
// 로그인 실패 후 결과 메시지 전달. 자동 호출됨.

@ -9,6 +9,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.HashMap;
@ -26,7 +27,7 @@ public class PublicApiController {
* @return {"password": "암호화 문자열"}
*/
@RequestMapping(value = "/public-api/passwordGenerator")
public ResponseEntity<?> passwordGenerator(Map<String, String> paramMap) {
public ResponseEntity<?> passwordGenerator(@RequestBody Map<String, String> paramMap) {
Map<String, String> resultMap = new HashMap<>();
String plainPassword = paramMap.get("password");
if(StringUtils.isNotEmpty(plainPassword)) {

@ -37,7 +37,7 @@ server:
include-exception: true
include-message: always
include-stacktrace: always
port: 443
port: 9443
ssl:
enabled: true
certificate: ${user.home}/.vite-plugin-mkcert/bsm-lab.dev.pem

Loading…
Cancel
Save