176만명의 커뮤니티!! 함께 토론해봐요.
해결됨
스프링부트 시큐리티 & JWT 강의
시큐리티 10강 페이스북 로그인을 하려고 하면 WARN 24016 --- [nio-8080-exec-2] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [231] milliseconds. 이런 에러가 발생합니다. 이 에러가 발생하기 전에 2. JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 이 에러가 먼저 발생해서 application.yml에 jpa: open-in-view: false이 코드를 추가해서 고쳤습니다. 2번을 고치고 나서 다시 실행해보니 1번 에러가 발생했는데 어떻게 고쳐야할지 모르겠습니다.
Lego
2023-07-10T15:03:11.045Z
댓글 1
좋아요 0
조회수 396
미해결
스프링부트 시큐리티 & JWT 강의
안녕하세요 강사님 궁금한 점이 해결되지 않아서 질문 남깁니다. 강사님 git에 있는 소스를 그대로 갖고 왔습니다. 토큰이 정상적인 상황일 때, 즉 username 값이 존재할 때 findByUsername을 사용해서 user객체를 얻는 장면인데 토큰 안에 User객체 자체를 저장해서 불필요한 DB연동을 안 하는 방식은 잘못된 방식인가요? 제 생각에는 이렇게 사용하면 토큰에 User 정보가 노출되기 때문에 보안이 취약하다 라고 생각하는데 이 생각이 맞는지 궁금합니다. username은 충분히 겹칠 수 있는 값이라고 생각이 드는데 토큰을 저장할 때 Id값을 저장해서 꺼내오는 방식은 잘못된 방식일까요?
진짜 잘하고싶다
2023-07-09T08:34:29.593Z
댓글 1
좋아요 0
조회수 500
미해결
스프링부트 시큐리티 & JWT 강의
수업 듣다가 궁금증이 생겨서 남깁니다. key 생성 시에 현재 실습에서는 "cos" 를 사용했는데, 실제로 사용할때는 key를 어떻게 생성하고, 보관해야하는지 궁금합니다.
공부해야지
2023-07-09T03:21:33.695Z
댓글 1
좋아요 0
조회수 275
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
ejs와 cjs 둘 중 express 프레임워크를 사용해서 프로그래밍을 하려면 어떤 방식을 추천하시나요?
node.js mysql mongodb express typescript socket.io jwt
박동규
2023-07-08T06:13:07.352Z
댓글 1
좋아요 0
조회수 560
미해결
스프링부트 시큐리티 & JWT 강의
안녕하세요. 좋은 강의 만들어주셔서 감사합니다. 궁금한 점이 생겨서 질문드립니다. 강의에서는 UserDetails를 구현할 때 내부에 엔티티 자체를 넣어주셨는데 엔티티 자체를 넣는게 엔티티를 dto로 변환 후 넣는 것보다 좋나요?
heehee
2023-07-03T09:13:01.937Z
댓글 2
좋아요 0
조회수 468
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요 json부하테스트중에 에러표시나서 방화벽들어가서 mysql포트 확인하고 3306설정했는데 안되서 포트80도해보고 했는데 에러표시만뜹니다 https://binshuuuu.tistory.com/m/214 제가 따라한 설정입니다
node.js mysql mongodb express typescript socket.io jwt
Hongsun1
2023-07-03T05:38:55.828Z
댓글 1
좋아요 0
조회수 369
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
선생님 콘솔로그 쳐서 premium위치 찾아서req.user.Domains [5].type === 'premium' 했는데 true 나와서 해결했습니다 감사합니다 앞으로 콘솔로그 쳐서 하는 습관가져야겠습니다 정말 감사합니다 ^_^!!!
node.js mysql mongodb express typescript socket.io jwt
Hongsun1
2023-07-02T05:31:54.286Z
댓글 0
좋아요 1
조회수 303
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요 선생님 시퀄라이즈 강의를 듣는데 raw쿼리를 쓰는게 가능하더군요. spring + ibatis 로 주로 개발해와서 raw 쿼리가 익숙한데 실무에서는 시퀄라이즈 vs raw 쿼리 중에 어떤걸 많이 사용하는 편인가요..?
node.js mysql mongodb express typescript socket.io jwt
카이
2023-06-30T04:35:01.225Z
댓글 1
좋아요 1
조회수 285
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
선생님 어제 코드 감사합니다 아쉽게도 많이 배워야할것같아서 ㅠㅜ 혹시 제가 빠트린 코드가 있을까요 ? 아니면 다른부분 확인할 사항이 있을까요? 작성한 코드 올려드립니다 nodebird-api -> middlewares-> index.js const jwt = require("jsonwebtoken"); //토큰을 검사하는 미들웨어 const rateLimit = require("express-rate-limit"); const User = require("../models/user"); const { Domain } = require("../models/"); const cors = require("cors"); exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); } else { res.status(403).send("로그인 필요"); } }; exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { // 패스포트 통해서 로그인 안했으면 next(); } else { const message = encodeURIComponent("로그인한 상태입니다."); res.redirect(`/?error=${message}`); //localhost:8001? error=메시지 } }; //토근검사 exports.verifyToken = (req, res, next) => { try { res.locals.decoded = jwt.verify( req.headers.authorization, process.env.JWT_SECRET ); return next(); } catch (error) { if (error.name === "TokenExpiredError") { return res.status(419).json({ code: 419, message: "토큰이 만료되었습니다.", }); } return res.status(401).json({ code: 401, message: "유효하지 않은 토큰입니다.", }); } }; const limiter = rateLimit({ widowMs: 60 * 1000, max: (req, res) => { if (req.user?.Domains[0]?.type === "premium") { return 10; } return 1; }, handler(req, res) { res.status(this.statusCode).json({ code: this.statusCode, message: `1분에 ${ req.user?.Domains[0]?.type === "premium" ? "열" : "한" } 번만 요청 할 수 있습니다...`, }); }, }); exports.apiLimiter = async (req, res, next) => { let user; if (res.locals.decoded) { user = await User.findOne({ where: { id: res.locals.decoded.id }, include: { model: Domain }, }); } req.user = user; limiter(req, res, next); }; exports.deprecated = (req, res) => { res.status(410).json({ code: 410, message: "새로운 버전이 나왔습니다. 새로운 버전을 사용하세요", }); }; exports.corsWhenDomainMatches = async (req, res, next) => { const domain = await Domain.findOne({ where: { host: new URL(req.get("origin")).host }, }); if (domain) { cors({ origin: true, Credential: true, })(req, res, next); //미들웨어 확장패턴 } else { next(); } }; nodebird-api -> routes -> v2.js const express = require("express"); const { verifyToken, apiLimiter, corsWhenDomainMatches, } = require("../middlewares"); const { createToken, tokenTest, getMyPosts, getPostsByHashtag, } = require("../controllers/v2"); const cors = require("cors"); const router = express.Router(); router.use(corsWhenDomainMatches); router.use( cors({ origin: true, credentials: true, //쿠키요청 }) ); router.post("/token", apiLimiter, createToken); router.get("/test", verifyToken, apiLimiter, tokenTest); router.get("/posts/my", verifyToken, apiLimiter, getMyPosts); // GET /v2/posts/hashtag/:title router.get("/posts/hashtag/:title", verifyToken, apiLimiter, getPostsByHashtag); module.exports = router;
node.js mysql mongodb express typescript socket.io jwt
Hongsun1
2023-06-29T23:38:33.306Z
댓글 1
좋아요 1
조회수 457
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
exports.apiLimiter = async (req, res, next) => { let user; if (res.locals.decoded) { user = await User.findOne({ where: { id: res.locals.decoded.id } }); } rateLimit({ widowMs: 60 * 1000, max: user?.type === "premium" ? 10 : 1, handler(req, res) { res.status(this.statusCode).json({ code: this.statusCode, message: "1분에 열 번만 요청 할 수 있습니다...", }); }, })(req, res, next); }; Api 프리미엄고객만 1분에 열번만요청할수있게 미들웨어 확장패턴으로 만들었습니다 그런데 localhost:4000/myposts 접속해서 10 번이상새로고침해도 api가 제한이 안되고 제가작성한 게시글 목록만 뜹니다
node.js mysql mongodb express typescript socket.io jwt
Hongsun1
2023-06-27T11:00:11.649Z
댓글 1
좋아요 0
조회수 611
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
nodebird-api 미들웨어 index.js 타입이 any로 떠서 프리미엄이 체크가 안되고 계속 제가 작성한 게시글정보만 뜹니다 사용량제한 어떻게 하나요? ㅠㅠ const jwt = require("jsonwebtoken"); const rateLimit = require("express-rate-limit"); const User = require("../models/user"); exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); } else { res.status(403).send("로그인 필요"); } }; exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { next(); } else { const message = encodeURIComponent("로그인한 상태입니다."); res.redirect(`/?error=${message}`); } }; exports.verifyToken = (req, res, next) => { try { res.locals.decoded = jwt.verify( req.headers.authorization, process.env.JWT_SECRET ); return next(); } catch (error) { if (error.name === "TokenExpiredError") { return res.status(419).json({ code: 419, message: "토큰이 만료되었습니다.", }); } return res.status(401).json({ code: 401, message: "유효하지 않은 토큰입니다.", }); } }; exports.apiLimiter = rateLimit({ windowMs: 60 * 1000, // 1분 max: 1, handler(req, res) { res.status(this.statusCode).json({ code: this.statusCode, // 기본값 429 message: "1분에 한 번만 요청할 수 있습니다.", }); }, }); exports.apiLimiter = async (req, res, next) => { let user; if (res.locals.decoded) { user = await User.findOne({ where: { id: res.locals.decoded.id } }); } rateLimit({ widowMs: 60 * 1000, max: user?.type === "premium" ? 10 : 1, handler(req, res) { res.status(this.statusCode).json({ code: this.statusCode, message: "1분에 열 번만 요청 할 수 있습니다...", }); }, })(req, res, next); }; exports.deprecated = (req, res) => { res.status(410).json({ code: 410, message: "새로운 버전이 나왔습니다. 새로운 버전을 사용하세요", }); };
node.js mysql mongodb express typescript socket.io jwt
Hongsun1
2023-06-26T23:35:20.216Z
댓글 1
좋아요 0
조회수 262
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
nodebird-api 미들웨어 index.js코드 const jwt = require("jsonwebtoken"); const rateLimit = require("express-rate-limit"); const User = require("../models/user"); exports.isLoggedIn = (req, res, next) => { if (req.isAuthenticated()) { next(); } else { res.status(403).send("로그인 필요"); } }; exports.isNotLoggedIn = (req, res, next) => { if (!req.isAuthenticated()) { next(); } else { const message = encodeURIComponent("로그인한 상태입니다."); res.redirect(`/?error=${message}`); } }; exports.verifyToken = (req, res, next) => { try { res.locals.decoded = jwt.verify( req.headers.authorization, process.env.JWT_SECRET ); return next(); } catch (error) { if (error.name === "TokenExpiredError") { return res.status(419).json({ code: 419, message: "토큰이 만료되었습니다.", }); } return res.status(401).json({ code: 401, message: "유효하지 않은 토큰입니다.", }); } }; exports.apiLimiter = async (req, res, next) => { let user; if (res.locals.decoded) { user = await User.findOne({ where: { id: res.locals.decoded.id } }); } rateLimit({ windowMs: 60 * 1000, max: user?.type === "premium" ? 1000 : 10, handler(req, res) { res.status(this.statusCode).json({ code: this.statusCode, message: "1분에 열 번만 요청할 수 있습니다.", }); }, }); }; exports.deprecated = (req, res) => { res.status(410).json({ code: 410, message: "새로운 버전이 나왔습니다. 새로운 버전을 사용하세요", }); }; nodebird-api routes v2.js 코드 const express = require("express"); const { verifyToken, apiLimiter } = require("../middlewares"); const { createToken, tokenTest, getMyPosts, getPostsByHashtag, } = require("../controllers/v2"); const router = express.Router(); router.post("/token", apiLimiter, createToken); router.get("/test", verifyToken, apiLimiter, tokenTest); router.get("/posts/my", verifyToken, apiLimiter, getMyPosts); router.get("/posts/hashtag/:title", verifyToken, apiLimiter, getPostsByHashtag); module.exports = router; 프리미엄으로 클라이언트 비밀키 발급하고 프리미엄만 사용량제한 구현했는데 터미널에 GET/search/%EA%B3%A0%EC%96%91%EC%9D%B4 - - ms - - 이렇게 나오고 사이트로딩만 뜹니다 ㅜㅜ
node.js mysql mongodb express typescript socket.io jwt
2023-06-26T10:29:23.324Z
댓글 1
좋아요 0
조회수 364
미해결
스프링부트 시큐리티 & JWT 강의
JWT 로그인 부분에서 username만 검증하고 password는 검증하는 부분이 안보이는거 같은데 맞나요? @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("UsernamePasswordAuthenticationFilter :: JwtAuthenticationFilter()"); // 1. id, pw 받아서 try { // x-www-form-urlencoded 로 요청시 // BufferedReader br = request.getReader(); // String input = null; // while((input = br.readLine()) != null){ // System.out.println(input); // } // System.out.println(request.getInputStream().toString()); // json 으로 요청시 ObjectMapper om = new ObjectMapper(); User user = om.readValue(request.getInputStream(), User.class); // 토큰 만들기 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); // PrincipalDetailsService의 loadUserByUsername() 이 실행된 후 정상이면 Authentication이 리턴됨 // DB에 있는 username과 password가 일치한다. Authentication authentication = authenticationManager.authenticate(authenticationToken); // 매니져가 인증을해서 Authentication 객체를 만들어줌 PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal(); // System.out.println("ㅍㅍㅍ " + principalDetails.getUser().getUsername()); // 이게 조회가 된다는건 로그인 됫다는뜻 // System.out.println("---------------------------------"); // authentication 객체가 Security session 영역에 저장을 해야하고 그방법이 return return authentication; } catch (IOException e) { e.printStackTrace(); // 에러낫을때 떠넘겨 버리면 밑에 코드가 unreacheable 되서 컴파일 에러 } // 2. 정상인지 로그인 시도를 authenticationManager로 하면 PrincipalDetailsService loadUserByUsername() 가 실행됨 // 3. PrincipalDetails 를 세션에 담고 => 세션에 값이 있어야 권한 관리가 된다. (권한관리 안할거면 세션에 안담아도 됨) // 4. JWT 토큰을 만들어서 응답해주면 // System.out.println("================================"); return null; } 사용자 입력(username, password)만 받아서 검증없이 Authentication 객체 만들고 있고 @Service @RequiredArgsConstructor public class PrincipalDetailsService implements UserDetailsService { private final UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("PrincipalDetaiilsService :: loadUserByUsername()"); User userEntity = userRepository.findByUsername(username); System.out.println("DB Connection :: UserRepository"); return new PrincipalDetails(userEntity); } } loadUserByUsername 에서도 username 만 받아서 엔티티 생성하는데 어디서 password 검증도 하는건지 궁금합니다.
Universe New
2023-06-26T09:56:37.240Z
댓글 1
좋아요 0
조회수 1155
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요 선생님 강의를 보다보니 그림판에서 텍스트로 코딩을 하시는데 화살표함수 작성시 뒤에 구문이 자동으로 입력이 되던데 그림판에 어떤 플러그인을 설치하셨길래 이런 기능이 되는건지 궁금합니다.
node.js mysql mongodb express typescript socket.io jwt
카이
2023-06-25T04:33:35.830Z
댓글 1
좋아요 0
조회수 440
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요 11강에서 강의자료 ppt 파일을 올려주신다고 했는데 어디서 다운로드 받을수 있나요?
node.js mysql mongodb express typescript socket.io jwt
정상원
2023-06-20T18:01:47.638Z
댓글 1
좋아요 1
조회수 979
해결됨
[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
//auth.service.ts import { Injectable, UnprocessableEntityException } from '@nestjs/common'; import { UsersService } from '../users/users.service'; import * as bcrypt from 'bcrypt'; import { JwtService } from '@nestjs/jwt'; import { IAuthServiceGetAccessToken, IAuthServiceLogin, IAuthServiceSetRefreshToken, } from './interfaces/auth-service.interface'; @Injectable() export class AuthService { constructor( private readonly userService: UsersService, // private readonly jwtService: JwtService, ) {} async login({ email, password, context }: IAuthServiceLogin) { // 1. 이메일이 일치하는 유저를 DB에서 찾기 const user = await this.userService.findOneByEmail({ email }); // 2. 일치하는 유저가 없으면?! 에러 던지기!!! if (!user) throw new UnprocessableEntityException('존재하지 않는 이메일입니다.'); // 3. 일치하는 유저가 있지만, 비밀번호가 틀렸다면?! const isAuth = await bcrypt.compare(password, user.password); if (!isAuth) throw new UnprocessableEntityException('틀린 암호입니다.'); // 4. refreshToken(=JWT)을 만들어서 브라우저 쿠키에 저장해서 보내주기 this.setRefreshToken({ user, context }); // 5. 일치하는 유저도 있고, 비밀번호도 맞았다면?! // => accessToken(=JWT)을 만들어서 브라우저에 전달하기 return this.getAccessToken({ user }); } getAccessToken({ user }: IAuthServiceGetAccessToken): string { return this.jwtService.sign( { sub: user.id }, { secret: process.env.JWT_SECRET_KEY, expiresIn: process.env.JWT_ACCESS_TOKEN_EXPIRE, }, ); } setRefreshToken({ user, context }: IAuthServiceSetRefreshToken): void { const refreshToken = this.jwtService.sign( { sub: user.id }, { secret: process.env.JWT_REFRESH_SECRET_KEY, expiresIn: process.env.JWT_REFRESH_TOKEN_EXPIRE, }, ); //개발환경 context.res.setHeader( 'set-Cookie', `refreshToken=${refreshToken}; path=/;`, ); // 배포환경 // context.res.setHeader('set-Cookie', `refreshToken=${refreshToken}; path=/; domain=.mybacksite.com; SameSite=None; Secure; httpOnly`); // context.res.setHeader('Access-Control-Allow-Origin', 'https://myfrontsite.com'); } } 리프레쉬 토큰을 생성하는 과정에서 개발환경에 사용하는 context.res.setHeader( 'set-Cookie', `refreshToken=${refreshToken}; path=/;`, ); 이 코드에 'refreshToken'의 이름을 <한글>로 사용하게되면 graphql로 API테스트를 할때 read에 대한 에러를 발생시키더라구요. 쿠키의 이름을 바꿔서 생성하려고 했는데 한글로 생성이 되지 않는거는 nodejs의 기본 특성인걸까요!? 참고이미지로 아래에 이미지를 붙여봅니다~ 궁금해요~~~ 이런내용들은 nodejs 공식문서에서 제가 잘 못찾는건지 궁금합니다. 공식문서에도 있을것 같아서 찾아보려고했는데 잘 못찾겠더라구요ㅠㅜ..
zeler1004
2023-06-20T07:22:37.644Z
댓글 2
좋아요 0
조회수 514
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요. 9장강의를 듣고 추가 과제를 시도해보던 중 궁금증이 생겨 질문드립니다. 스스로 해보기 -> 팔로잉 끊기 에서 destory와 라우터를 사용하라고 안내해주셨는데 user자체를 삭제하는 것이 아닌 중간테이블(follow)에서 해당 로우만 삭제하는 방법이 따로 있나요? if (user) { const a = await user.destroy({ where: { Followings: { followerId: req.params.id } }, }); 위와 같이 방법을 여러가지로 시도해보았지만 계속해서 유저 삭제(탈퇴)가 되는 상황이라 도움주시면 감사하겠습니다..!
node.js mysql mongodb express typescript socket.io jwt
최지인
2023-06-20T06:51:00.651Z
댓글 1
좋아요 0
조회수 321
미해결
스프링부트 시큐리티 & JWT 강의
안녕하세요. 강사님! 수업 정말 잘 들었습니다! 비전공자로써 3개월째인데 JWT 강의 중에 정말 이해가 잘 되었습니다!!! 진심으로 감사합니다~~ 다름이 아니라 더 나아가서, JWT와 Oauth2를 붙이려고 하는데 JWT 강의 초반에 기존의 Oauth2 방식을 사용하지 않고 다른 방식을 써야 된다고 하셔서 질문합니다. 어떤 부분이 달라져야할지 전혀 감이 안 오는데, 제가 조금 참고할만한 자료가 있을까요? 혹시 JWT+Oauth를 붙이려고 할 때 코드가 많이 변경될까요? (혹시 강의 제작하실 생각 없으신가요...ㅎㅎ)
spring spring-security jwt oauth2
Lee jeonghui
2023-06-16T08:03:01.280Z
댓글 1
좋아요 0
조회수 813
미해결
스프링부트 시큐리티 & JWT 강의
configureViewResolvers 을 오버라이딩 했을때 내부구성을 요렇게 바꿔 주세요를 하셨을때 요렇게를 어떻게 요렇게 바꾸나요?
seongbin
2023-06-15T02:50:57.638Z
댓글 2
좋아요 0
조회수 826
해결됨
Spring Boot JWT Tutorial
[코드](https://github.com/YuYoHan/JWT) ECDSA signing keys must be PrivateKey instances.이런 오류가 뜨는데 JwtProvider입니다. @Slf4j @Component public class JwtProvider implements InitializingBean { private static final String AUTHORITIES_KEY = "auth"; private final String secret; private final long tokenValidityInMilliseconds; private Key key; public JwtProvider(@Value("${jwt.secret_key}") String secret, @Value("${jwt.access.expiration}") long tokenValidityInMilliseconds ) { this.secret = secret; this.tokenValidityInMilliseconds = tokenValidityInMilliseconds * 1000; } // 여기서 InitializingBean를 상속받고 이 메소드를 오버라이드한 이유는 // Bean이 생성이 되고 생성자를 통해서 secret 값을 Base64 Decode해서 key 변수에 할당하기 위함이다. @Override public void afterPropertiesSet() throws Exception { byte[] keyBytes = Decoders.BASE64.decode(secret); this.key = Keys.hmacShaKeyFor(keyBytes); } // 유저 정보를 가지고 AccessToken, RefreshToken을 생성하는 메서드 public TokenDTO createToken(Authentication authentication) { // 권한 가져오기 String authorities = authentication.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); long now = (new Date()).getTime(); // Access Token 생성 Date accessTokenExpire = new Date(now + this.tokenValidityInMilliseconds); String accessToken = Jwts.builder() .setSubject(authentication.getName()) .claim(AUTHORITIES_KEY, authorities) .setExpiration(accessTokenExpire) .signWith( key, SignatureAlgorithm.ES512) .compact(); // Refresh Token 생성 Date refreshTokenExpire = new Date(now + this.tokenValidityInMilliseconds + 86400); String refreshToken = Jwts.builder() .setSubject(authentication.getName()) .claim(AUTHORITIES_KEY, authorities) .setExpiration(refreshTokenExpire) .signWith(key, SignatureAlgorithm.ES512) .compact(); return TokenDTO.builder() .grantType("Bearer") .accessToken(accessToken) .refreshToken(refreshToken) .build(); } // JWT 토큰을 복호화하여 토큰에 들어있는 정보를 꺼내는 코드 // 토큰으로 클레임을 만들고 이를 이용해 유저 객체를 만들어서 최종적으로 authentication 객체를 리턴 // 인증 정보 조회 public Authentication getAuthentication(String token) { // 토큰 복호화 메소드 Claims claims = parseClaims(token); if(claims.get("auth") == null) { throw new RuntimeException("권한 정보가 없는 토큰입니다."); } // 클레임 권한 정보 가져오기 Collection<? extends GrantedAuthority> authorities = Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); // UserDetails 객체를 만들어서 Authentication 리턴 User principal = new User(claims.getSubject(), "", authorities); return new UsernamePasswordAuthenticationToken(principal, token, authorities); } private Claims parseClaims(String token) { try { return Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); } catch (ExpiredJwtException e) { return e.getClaims(); } } // 토큰의 유효성 검증을 수행 public boolean validateToken(String token) { try { Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); return true; } catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { log.info("잘못된 JWT 서명입니다."); } catch (ExpiredJwtException e) { log.info("만료된 JWT 토큰입니다."); } catch (UnsupportedJwtException e) { log.info("지원되지 않는 JWT 토큰입니다."); } catch (IllegalArgumentException e) { log.info("JWT 토큰이 잘못되었습니다."); } return false; } } 강의랑 같은데 오류가 발생하네요 ㅠㅠ
유요한
2023-06-14T09:40:50.084Z
댓글 2
좋아요 0
조회수 592