Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 자료구조와 함께 배우는 알고리즘 입문
- 이터레이터
- GIT
- 데비안
- 처음 만나는 AI수학 with Python
- 구멍가게코딩단
- 코드로배우는스프링웹프로젝트
- 처음 만나는 AI 수학 with Python
- 자료구조와함께배우는알고리즘입문
- iterator
- resttemplate
- ㅒ
- 알파회계
- 스프링 시큐리티
- 친절한SQL튜닝
- 페이징
- network configuration
- 서버설정
- baeldung
- 리눅스
- 목록처리
- 스프링부트핵심가이드
- /etc/network/interfaces
- 티스토리 쿠키 삭제
- 선형대수
- d
- 자바편
- Kernighan의 C언어 프로그래밍
- 코드로배우는스프링부트웹프로젝트
- 네트워크 설정
Archives
- Today
- Total
bright jazz music
blog 35 : JWT를 이용한 인증 - 만들어보자 본문
1. 사용할 JWT 라이브러리 선택
가장 사용자가 많은 라이브러리를 사용한다.
2. build.gradle에 의존성 주입
//build.gradle
//jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
2. 사용
//AuthController.java
package com.endofma.blog.controller;
import com.endofma.blog.request.Login;
import com.endofma.blog.response.SessionResponse;
import com.endofma.blog.service.AuthService;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.ResponseCookie;
//import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
//jwt
import java.security.Key;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.SignatureAlgorithm;
import java.time.Duration;
import java.util.Base64;
@Slf4j
@RestController
@RequiredArgsConstructor
public class AuthController {
//생성자를 통한 주입
//private final UserRepository userRepository;
//로그인 및 인증 절차를 서비스에 위임
private final AuthService authService;
//AuthController.java
@PostMapping("/auth/login")
// public ResponseEntity<Object> login(@RequestBody Login login){
public SessionResponse login(@RequestBody Login login){
String accessToken = authService.signin(login);
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); 이렇게 하면 요청이 올 때마다 key 값이 다르게 저장된다. 따라서 일반적으로는 고정하여 사용한다.
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
byte [] encodedKey = key.getEncoded();
String strKey = Base64.getEncoder().encodeToString(encodedKey);
String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();
return new SessionResponse(jws);
}
}
auth.http
POST http://localhost:8080/auth/login
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 20 Feb 2023 13:05:14 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.wl9wC-M2XhboVIM06CoVhAy7Bafh71rA5kPT9laUPqQ"
}
Response file saved.
> 2023-02-20T220514.200.json
Response code: 200; Time: 555ms (555 ms); Content length: 101 bytes (101 B)
Cookies are preserved between requests:
> D:\personal\blog\.idea\httpRequests\http-client.cookies
토큰을 반환해 주는 것을 확인할 수 있다.
3. 값 들어가는지 확인해보기
//AuthController.java
package com.endofma.blog.controller;
import com.endofma.blog.request.Login;
import com.endofma.blog.response.SessionResponse;
import com.endofma.blog.service.AuthService;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.ResponseCookie;
//import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
//jwt
import java.security.Key;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.SignatureAlgorithm;
import java.time.Duration;
import java.util.Base64;
@Slf4j
@RestController
@RequiredArgsConstructor
public class AuthController {
//생성자를 통한 주입
//private final UserRepository userRepository;
//로그인 및 인증 절차를 서비스에 위임
private final AuthService authService;
//AuthController.java
@PostMapping("/auth/login")
// public ResponseEntity<Object> login(@RequestBody Login login){
public SessionResponse login(@RequestBody Login login){
String accessToken = authService.signin(login);
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); 이렇게 하면 요청이 올 때마다 key 값이 다르게 저장된다. 따라서 일반적으로는 고정하여 사용한다.
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
byte [] encodedKey = key.getEncoded();
String strKey = Base64.getEncoder().encodeToString(encodedKey);
String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();
return new SessionResponse(jws);
}
}
//AuthResolver.java
package com.endofma.blog.config;
import com.endofma.blog.config.data.UserSession;
import com.endofma.blog.domain.Session;
import com.endofma.blog.exception.Unauthorized;
import com.endofma.blog.repository.SessionRepository;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@Slf4j
@RequiredArgsConstructor
public class AuthResolver implements HandlerMethodArgumentResolver {
//주입
private final SessionRepository sessionRepository;
@Override
public boolean supportsParameter(MethodParameter parameter) {
//컨트롤러에서 사용할 어노테이션이나 DTO가 사용자가 사용하려는 것이 맞는지, 지원하는지 체크한다.
return parameter.getParameterType().equals(UserSession.class); //UserSession 클래스를 사용하는 것이 맞는지 확인. 맞으면 컨트롤러에 값 할당
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//실제로 해당 DTO에 값을 세팅해준다.
String jws = webRequest.getHeader("Authorization"); //헤더의 값으로 확인해준다.
if (jws == null || jws.equals("")){
throw new Unauthorized();
}
try {
Jwts.parserBuilder()
.setSigningKey("C") //사인값 추가
.build()
.parseClaimsJws(jws);
//OK, we can trust this JWT
} catch (JwtException e) {
throw new Unauthorized();
//don't trust the JWT!
}
//db를 조회할 필요 없기 때문에 주석처리
// Session session = sessionRepository.findByAccessToken(accessToken)
// .orElseThrow(Unauthorized::new);
return null;
}
}
### auth.http
POST http://localhost:8080/auth/login
Content-Type: application/json
{
"email" : "catnails@gmail.com",
"password" : "1234"
}
4. 값 만들어서 인증하기
//AuthResolver.java
package com.endofma.blog.config;
import com.endofma.blog.config.data.UserSession;
import com.endofma.blog.domain.Session;
import com.endofma.blog.exception.Unauthorized;
import com.endofma.blog.repository.SessionRepository;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@Slf4j
@RequiredArgsConstructor
public class AuthResolver implements HandlerMethodArgumentResolver {
//주입
private final SessionRepository sessionRepository;
private final String KEY = "Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=";
@Override
public boolean supportsParameter(MethodParameter parameter) {
//컨트롤러에서 사용할 어노테이션이나 DTO가 사용자가 사용하려는 것이 맞는지, 지원하는지 체크한다.
return parameter.getParameterType().equals(UserSession.class); //UserSession 클래스를 사용하는 것이 맞는지 확인. 맞으면 컨트롤러에 값 할당
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//실제로 해당 DTO에 값을 세팅해준다.
String jws = webRequest.getHeader("Authorization"); //헤더의 값으로 확인해준다.
if (jws == null || jws.equals("")){
throw new Unauthorized();
}
byte[] decodedKey = Base64.decodeBase64(KEY); //스트링 값이었던 것을 바이트 값으로 변환한다. setSigningKey(String)이 폐기되어서.
try {
Jws<Claims> claims = Jwts.parserBuilder()
// .setSigningKey(KEY) //사인값 추가 deprecated
.setSigningKey(decodedKey) //파라미터로 바이트 값이 들어간다.
.build()
.parseClaimsJws(jws);
log.info(">>>>>{}", claims );
//OK, we can trust this JWT
} catch (JwtException e) {
throw new Unauthorized();
//don't trust the JWT!
}
// Cookie[] cookies = servletRequest.getCookies(); //배열로 받는다.
// if (cookies.length == 0) {
// log.error("쿠키가 없음");
// throw new Unauthorized();
// }
// String accessToken = cookies[0].getValue();
//db를 조회할 필요 없기 때문에 주석처리
// Session session = sessionRepository.findByAccessToken(accessToken)
// .orElseThrow(Unauthorized::new);
// return new UserSession(1L);
// return new UserSession(session.getUser().getId()); //컨트롤러로 넘겨준다.
return null;
}
}
//AuthController.java
package com.endofma.blog.controller;
import com.endofma.blog.request.Login;
import com.endofma.blog.response.SessionResponse;
import com.endofma.blog.service.AuthService;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.ResponseCookie;
//import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
//jwt
import java.security.Key;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import java.time.Duration;
import java.util.Base64;
@Slf4j
@RestController
@RequiredArgsConstructor
public class AuthController {
//생성자를 통한 주입
//private final UserRepository userRepository;
//로그인 및 인증 절차를 서비스에 위임
private static final String KEY = "Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=";
private final AuthService authService;
//앞으로 인증에 사용할 암호화 키. 유출되어서는 안 된다. 여기에는 테스트용으로 사용하기 위해 적어 놓는다.
//AuthController.java
@PostMapping("/auth/login")
// public ResponseEntity<Object> login(@RequestBody Login login){
public SessionResponse login(@RequestBody Login login){
String accessToken = authService.signin(login);
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); 이렇게 하면 요청이 올 때마다 key 값이 다르게 저장된다. 따라서 일반적으로는 고정하여 사용한다.
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
SecretKey key = Keys.hmacShaKeyFor(Base64.getDecoder().decode(KEY));
// 키 값을 복호화 하여 보기 위해 추가한 코드.
// byte [] encodedKey = key.getEncoded();
// String strKey = Base64.getEncoder().encodeToString(encodedKey);
//base64는 바이트를 스트링으로, 또는 그 반대로 변환한다.
//Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=
String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();
return new SessionResponse(jws);
}
}
5. 최종 수정
AuthController.java
//AuthController.java
package com.endofma.blog.controller;
import com.endofma.blog.request.Login;
import com.endofma.blog.response.SessionResponse;
import com.endofma.blog.service.AuthService;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.ResponseCookie;
//import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
//jwt
import java.security.Key;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import java.time.Duration;
import java.util.Base64;
@Slf4j
@RestController
@RequiredArgsConstructor
public class AuthController {
//생성자를 통한 주입
//private final UserRepository userRepository;
//로그인 및 인증 절차를 서비스에 위임
private static final String KEY = "Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=";
private final AuthService authService;
//앞으로 인증에 사용할 암호화 키. 유출되어서는 안 된다. 여기에는 테스트용으로 사용하기 위해 적어 놓는다.
//AuthController.java
@PostMapping("/auth/login")
// public ResponseEntity<Object> login(@RequestBody Login login){
public SessionResponse login(@RequestBody Login login){
Long userId = authService.signin(login);
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); 이렇게 하면 요청이 올 때마다 key 값이 다르게 저장된다. 따라서 일반적으로는 고정하여 사용한다.
// Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
SecretKey key = Keys.hmacShaKeyFor(Base64.getDecoder().decode(KEY));
// 키 값을 복호화 하여 보기 위해 추가한 코드.
// byte [] encodedKey = key.getEncoded();
// String strKey = Base64.getEncoder().encodeToString(encodedKey);
//base64는 바이트를 스트링으로, 또는 그 반대로 변환한다.
//Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=
String jws = Jwts.builder().setSubject(String.valueOf(userId)).signWith(key).compact();
return new SessionResponse(jws);
}
}
AuthService.java
//AuthService.java
package com.endofma.blog.service;
import com.endofma.blog.domain.Session;
import com.endofma.blog.domain.User;
import com.endofma.blog.exception.InvalidSigninInformation;
import com.endofma.blog.repository.UserRepository;
import com.endofma.blog.request.Login;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
@RequiredArgsConstructor
public class AuthService {
private final UserRepository userRepository;
@Transactional
// public String signin(Login login){
public Long signin(Login login){
User user = userRepository.findByEmailAndPassword(login.getEmail(), login.getPassword())
.orElseThrow(InvalidSigninInformation::new);
//세션 발급
Session session = user.addSession();
// return session.getAccessToken();
return user.getId();
}
}
AuthResolver.java
//AuthResolver.java
package com.endofma.blog.config;
import com.endofma.blog.config.data.UserSession;
import com.endofma.blog.domain.Session;
import com.endofma.blog.exception.Unauthorized;
import com.endofma.blog.repository.SessionRepository;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@Slf4j
@RequiredArgsConstructor
public class AuthResolver implements HandlerMethodArgumentResolver {
//주입
private final SessionRepository sessionRepository;
private final String KEY = "Kz06PMZdP03FQVS3m8Jg9gKSEQjV4/NePMOq1F0GNH4=";
@Override
public boolean supportsParameter(MethodParameter parameter) {
//컨트롤러에서 사용할 어노테이션이나 DTO가 사용자가 사용하려는 것이 맞는지, 지원하는지 체크한다.
return parameter.getParameterType().equals(UserSession.class); //UserSession 클래스를 사용하는 것이 맞는지 확인. 맞으면 컨트롤러에 값 할당
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//실제로 해당 DTO에 값을 세팅해준다.
String jws = webRequest.getHeader("Authorization"); //헤더의 값으로 확인해준다.
if (jws == null || jws.equals("")){
throw new Unauthorized();
}
byte[] decodedKey = Base64.decodeBase64(KEY); //스트링 값이었던 것을 바이트 값으로 변환한다. setSigningKey(String)이 폐기되어서.
try {
Jws<Claims> claims = Jwts.parserBuilder()
// .setSigningKey(KEY) //사인값 추가 deprecated
.setSigningKey(decodedKey) //파라미터로 바이트 값이 들어간다.
.build()
.parseClaimsJws(jws);
String userId = claims.getBody().getSubject();
return new UserSession(Long.parseLong(userId));
//OK, we can trust this JWT
} catch (JwtException e) {
throw new Unauthorized();
//don't trust the JWT!
}
// Cookie[] cookies = servletRequest.getCookies(); //배열로 받는다.
// if (cookies.length == 0) {
// log.error("쿠키가 없음");
// throw new Unauthorized();
// }
// String accessToken = cookies[0].getValue();
//db를 조회할 필요 없기 때문에 주석처리
// Session session = sessionRepository.findByAccessToken(accessToken)
// .orElseThrow(Unauthorized::new);
// return new UserSession(1L);
// return new UserSession(session.getUser().getId()); //컨트롤러로 넘겨준다.
}
}
PostController.java
//PostController.java
package com.endofma.blog.controller;
import com.endofma.blog.config.data.UserSession;
import com.endofma.blog.domain.Post;
import com.endofma.blog.exception.InvalidRequest;
import com.endofma.blog.request.PostCreate;
import com.endofma.blog.request.PostEdit;
import com.endofma.blog.request.PostSearch;
import com.endofma.blog.response.PostResponse;
import com.endofma.blog.service.PostService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequiredArgsConstructor
public class PostController {
//에러는 ExceptionController에서 처리한다.
private final PostService postService;
//postController.java
@GetMapping("/foo")
public Long foo(UserSession userSession){
log.info(">>> {}", userSession.id);
return userSession.id;
}
@GetMapping("/bar")
public String bar(UserSession userSession){
log.info(">>> {}", userSession.id);
return "인증이 필요한 페이지";
}
//PostController.java
@PostMapping("/posts")
public void post(@RequestBody @Valid PostCreate request) {
//인증 방법
//1. GET Parameter : @RequestParam String authorization
//2. POST(body) value : 사용하지 않을 예쩡. PostCreate에 인증 코드를 추가해야 해서 설계가 무너진다. private String authrozation 같은.
//3. Header로 받는 방법 : @RequestHeader String authorization
//PostController의 post()에 보내는 요청의 제목에 "바보"라는 글자를 넣을 수 없다면.
// if(request.getTitle().contains("바보")){
// throw new InvalidRequest();
// } 이렇게 데이터를 꺼내서 분리해서 재조립하는 방식보다는 아래처럼 메시지를 통해 가져오는 방식 권장
request.validate(); //검증
postService.write(request);
// return Map.of();
}
//단건 조회
@GetMapping("/posts/{postId}")
public PostResponse get(@PathVariable Long postId){
PostResponse response = postService.get(postId);
return response;
}
//여러 글 조회(글 목록 가져오기)
// /posts
@GetMapping("/posts")
//글이 너무 많은 경우 비용이 너무 많이 든다.
//DB가 뻗을 수 있음.
//DB -> 애플리케이션 서버로 전달하는 시간, 트래픽 비용이 많이 발생할 수 있다.
//따라서 페이지 설정
// 원래는 int로 받았음
// public List<PostResponse> getList(@RequestParam int page){
// 그러나 사용의 용이성을 위해 pageable을 사용함
// public List<PostResponse> getList(@PageableDefault Pageable pageable){ //1로 넘겨도 0으로 보정해서 넣어줌.
//근데 PageableDefault의 기본 size가 10이라 yml에서 설정해도 먹히지 않는다.
//이 떄는 어노테이션을 그대로 유지하면서 size를 파라미터로 넣어주는 방법이 있다.
//public List<PostResponse> getList(@PageableDefault(size=10) Pageable pageable){
//또는 어노테이션을 빼고 application.yml에서 default-page-size를 설정하여 해결할 수 수있다.
//전에는 Pageable을 사용했으나 여러 요구사항을 수용 할 수 있는 클래스를 사용하기 위해
//postSearch 클래스 사용
public List<PostResponse> getList(@ModelAttribute PostSearch postSearch){//따로 만든 요청클래스 사용하려고 함
// public List<PostResponse> getList(Pageable pageable){
return postService.getList(postSearch);
}
@PatchMapping("/posts/{postId}")
public void edit(@PathVariable Long postId, @RequestBody @Valid PostEdit request){
postService.edit(postId, request);
}
@DeleteMapping("/posts/{postId}")
public void delete(@PathVariable Long postId){
postService.delete(postId);
System.out.println("hello world2");
System.out.println("test for test branch1");
}
}
먼저 토큰 얻기
### auth.http
POST http://localhost:8080/auth/login
Content-Type: application/json
{
"email" : "catnails@gmail.com",
"password" : "1234"
}
토큰 값:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.MFZVLmx0p7Y-P16K7gXRVQaaC3ghTpCqaivUoBEX0vM
###post.http
### 주석 #3개
GET http://localhost:8080/foo
Content-Type: application/json
Authorization: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.MFZVLmx0p7Y-P16K7gXRVQaaC3ghTpCqaivUoBEX0vM
토큰 값 사용하여 /foo api 접근
'Projects > blog' 카테고리의 다른 글
blog37 : JWT를 이용한 인증 - 암호화 키 분리 및 개선 (0) | 2023.02.23 |
---|---|
blog36 : JWT를 이용한 인증 - application.yml 커스텀 설정값 만들기 (0) | 2023.02.22 |
blog33 : 쿠키를 통한 인증 및 검증 (0) | 2023.02.16 |
blog32 : 데이터베이스를 통한 토큰 검증 (0) | 2023.02.16 |
blog 31 : 세션 토큰 발급기능 추가 2 (0) | 2023.02.15 |
Comments