쓰기 들어가야함
This commit is contained in:
16
src/front/src/middlewares/authentication.js
Normal file
16
src/front/src/middlewares/authentication.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default async function () {
|
||||||
|
try {
|
||||||
|
const token = this.$cookie.get('accessToken');
|
||||||
|
const result = await axios({
|
||||||
|
method: 'get',
|
||||||
|
url: '/api/users',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + token
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-for="article in articles" v-bind:key="article.id">
|
<article v-for="article in articles" v-bind:key="article.id">
|
||||||
{{ article.title }}
|
<span>{{ article.title }}</span>
|
||||||
|
<span>{{ article }}</span>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<router-link to="/articles/write">글쓰기</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import articleApi from "../../api/articleApi";
|
import articleApi from "../../api/articleApi";
|
||||||
|
import authApi from "../../api/authApi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "index",
|
name: "List",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
articles: [],
|
articles: [],
|
||||||
@@ -17,6 +24,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async beforeCreate() {
|
async beforeCreate() {
|
||||||
|
try {
|
||||||
|
await authApi.session(this.$cookie.get('accessToken'));
|
||||||
|
} catch (e) {
|
||||||
|
alert('토큰이 존재하지 않거나 올바르지 않은 토큰입니다.');
|
||||||
|
await this.$router.push('/');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await articleApi.getArticles.bind(this)({});
|
const result = await articleApi.getArticles.bind(this)({});
|
||||||
this.articles = result.data;
|
this.articles = result.data;
|
||||||
21
src/front/src/pages/articles/Write.vue
Normal file
21
src/front/src/pages/articles/Write.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<form ></form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import articleApi from "../../api/articleApi";
|
||||||
|
import authApi from "../../api/authApi";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Write",
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
const result = await authApi.login({email, password});
|
const result = await authApi.login({email, password});
|
||||||
const { token } = result.data;
|
const { token } = result.data;
|
||||||
this.$cookie.set('accessToken', token, 1000);
|
this.$cookie.set('accessToken', token, 1000);
|
||||||
|
await this.$router.push('/articles');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import VueRouter from "vue-router";
|
|||||||
import Welcome from "../pages/Welcome";
|
import Welcome from "../pages/Welcome";
|
||||||
import Login from "../pages/auth/Login";
|
import Login from "../pages/auth/Login";
|
||||||
import Register from "../pages/auth/Register";
|
import Register from "../pages/auth/Register";
|
||||||
import Articles from "../pages/articles";
|
import Articles from "../pages/articles/List";
|
||||||
|
import WriteArticle from '../pages/articles/Write';
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
@@ -26,6 +27,10 @@ export const router = new VueRouter({
|
|||||||
{
|
{
|
||||||
path: '/articles',
|
path: '/articles',
|
||||||
component: Articles
|
component: Articles
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/articles/write',
|
||||||
|
component: WriteArticle
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.example.vue.config.security;
|
package com.example.vue.config.security;
|
||||||
|
|
||||||
|
import com.example.vue.domain.auth.AuthException;
|
||||||
import com.example.vue.domain.user.User;
|
import com.example.vue.domain.user.User;
|
||||||
import com.example.vue.util.JwtUtil;
|
import com.example.vue.util.JwtUtil;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.JwtException;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -31,6 +33,7 @@ public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
|
||||||
Authentication authentication = getAuthentication(request);
|
Authentication authentication = getAuthentication(request);
|
||||||
|
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
@@ -49,13 +52,18 @@ public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Claims claims = jwtUtil.getClaims(token.substring("Bearer ".length()));
|
Claims claims;
|
||||||
|
|
||||||
|
try {
|
||||||
|
claims = jwtUtil.getClaims(token.substring("Bearer ".length()));
|
||||||
|
} catch (JwtException e) {
|
||||||
|
throw new AuthException.MalformedJwt(token);
|
||||||
|
}
|
||||||
|
|
||||||
Set<GrantedAuthority> roles = new HashSet<>();
|
Set<GrantedAuthority> roles = new HashSet<>();
|
||||||
String role = (String) claims.get("role");
|
String role = (String) claims.get("role");
|
||||||
roles.add(new SimpleGrantedAuthority("ROLE_" + role));
|
roles.add(new SimpleGrantedAuthority("ROLE_" + role));
|
||||||
|
|
||||||
// return new UsernamePasswordAuthenticationToken(claims, null, roles);
|
|
||||||
return new UsernamePasswordAuthenticationToken(new User(claims), null, roles);
|
return new UsernamePasswordAuthenticationToken(new User(claims), null, roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.example.vue.domain.article;
|
package com.example.vue.domain.article;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
import org.springframework.data.annotation.CreatedDate;
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
import org.springframework.data.annotation.LastModifiedDate;
|
||||||
|
|
||||||
@@ -10,6 +11,7 @@ import java.time.LocalDateTime;
|
|||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
@NamedQuery(name = "findAll", query = "select a from Article a order by a.createdAt desc")
|
@NamedQuery(name = "findAll", query = "select a from Article a order by a.createdAt desc")
|
||||||
|
@NoArgsConstructor
|
||||||
public class Article {
|
public class Article {
|
||||||
|
|
||||||
@Id @GeneratedValue
|
@Id @GeneratedValue
|
||||||
@@ -27,4 +29,18 @@ public class Article {
|
|||||||
@LastModifiedDate
|
@LastModifiedDate
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
public Article(ArticleRequestDto articleRequestDto) {
|
||||||
|
this.title = articleRequestDto.getTitle();
|
||||||
|
this.content = articleRequestDto.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
private void prePersist() {
|
||||||
|
this.createdAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreUpdate
|
||||||
|
private void preUpdate() {
|
||||||
|
this.updatedAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package com.example.vue.domain.article;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -17,7 +16,11 @@ public class ArticleController {
|
|||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public List<ArticleResponseDto> getArticles(Pageable pageable) {
|
public List<ArticleResponseDto> getArticles(Pageable pageable) {
|
||||||
List<ArticleResponseDto> articles = articleService.findAll(pageable);
|
return articleService.findAll(pageable);
|
||||||
return articles;
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public ArticleResponseDto postArticles(@RequestBody @Valid ArticleRequestDto articleRequestDto) {
|
||||||
|
return articleService.save(articleRequestDto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ public class ArticleRepository {
|
|||||||
|
|
||||||
private final EntityManager em;
|
private final EntityManager em;
|
||||||
|
|
||||||
|
public Article save(Article article) {
|
||||||
|
em.persist(article);
|
||||||
|
return article;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Article> findAll(Pageable pageable) {
|
public List<Article> findAll(Pageable pageable) {
|
||||||
int page = pageable.getPageNumber();
|
int page = pageable.getPageNumber();
|
||||||
int size = pageable.getPageSize();
|
int size = pageable.getPageSize();
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.example.vue.domain.article;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ArticleRequestDto {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.example.vue.domain.article;
|
package com.example.vue.domain.article;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -14,6 +13,11 @@ public class ArticleService {
|
|||||||
|
|
||||||
private final ArticleRepository articleRepository;
|
private final ArticleRepository articleRepository;
|
||||||
|
|
||||||
|
public ArticleResponseDto save(ArticleRequestDto articleRequestDto) {
|
||||||
|
Article article = articleRepository.save(new Article(articleRequestDto));
|
||||||
|
return new ArticleResponseDto(article);
|
||||||
|
}
|
||||||
|
|
||||||
public List<ArticleResponseDto> findAll(Pageable pageable) {
|
public List<ArticleResponseDto> findAll(Pageable pageable) {
|
||||||
return articleRepository.findAll(pageable)
|
return articleRepository.findAll(pageable)
|
||||||
.stream()
|
.stream()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.example.vue.domain.auth;
|
package com.example.vue.domain.auth;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.JwtException;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
@@ -25,4 +26,11 @@ public class AuthException {
|
|||||||
super("이미 존재하는 사용자입니다. [email=" + email + "]");
|
super("이미 존재하는 사용자입니다. [email=" + email + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||||
|
public static class MalformedJwt extends JwtException {
|
||||||
|
public MalformedJwt(String token) {
|
||||||
|
super("올바르지 않은 토큰 입니다. [token=" + token + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user