[TIL] 23.02.14 게시판 2 jwt토큰으로 이루어진 서버로 vsc와 통신하여 프론트 구현

hyewon jeong·2023년 2월 14일
1

TIL

목록 보기
92/138

우선 회원가입 및 로그인 하여 jwt 토큰 값을 받아야 함으로 먼저 임시로 사용한 로그인 구현 한다. ( 나의 경우 init data 로 스프링 구동시 유저를 가입시켜 놓았기 때문에 바로 로그인하면된다. )

📌 1.사전 준비

1. VS code 설치


[extends]→ [live server] 설치 웹페이지를 보여주는 기능

1. 부트스트랩 사용시 다운로드

CDN via jsDelivr

Skip the download with jsDelivr to deliver cached version of Bootstrap’s compiled CSS and JS to your project.

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>

If you’re using our compiled JavaScript and prefer to include Popper separately, add Popper before our JS, via a CDN preferably.

<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js" integrity="sha384-mQ93GR66B00ZXjt0YO5KlohRA5SY2XofN4zfuZxLkoj1gXtW8ANNCe9d5Y3eG5eD" crossorigin="anonymous"></script>

우리가 사용할 부분은 CDN이므로 직접 다운받아 폴더에 넣어주는 방식이 아니라 저기 있는것들을 복사해서
html 코드에 붙여넣기만 하면 부트스트랩에 정의되어 있는 css와 js를 사용할 수 있기때문에 좀 더 편합니다.

이 사이트를 켜놓은 다음 html 코드를 작성할 vscode를 켜봅시다.

2. template ecommerce bootstrap free 검색 하면 다양한 무료 샘플들을 지원한다.

Themewagon

  • 사용법 : https://themewagon.com/ 에서 원하는 탬플릿을 압축파일로 다운받아 푼 후 vs code에서 폴더채로 연다.

codepen

  • 사용법 : https://codepen.io/trending 에서 sign up 등 검색하면 각종 탬플릿을 이용할 수 있다.

  • 해당 코드들이 나와있음

  • HTML 코드의 경우 복잡하게 코드가 되어 있을땐 ✔클릭 후 Analyze HTML 을 클릭하면 평소 우리가 알던 코드로 변경됨
    이대로 복사하여 vs code의 html 로 붙여넣기 한다.
    (필요시 ! 탭 으로 자동 코드 생성 후 진행)

  • CSS와 JS 는 안에서 만들어서 안에 넣어주자. (갠취)

  - css 는 <style></style> 적은 후 이 사이에 코드 삽입
  - JS  는 <script></script>적은 후 이 사이에 코드 삽입

🎈 jQuiry(JS)를 사용하기 위해서는 임포트를 해줘야한다.
두가지 방법 중

첫번째 방법 은 헤더에 아래 코드 추가 하고, 코드에 해당하는 js파일 두개를 넣어줘야한다.

// $ 에러 발생시 jquery 사용하겠다고 헤드에 추가 하면 해결 
<head>
    <script src="js/jquery-3.3.1.min.js"></script>
    <script src="js/jquery-ui.js"></script>
</head>

두번째 방법은 임포트한다.

 <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
 안될시 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

📌 2.임시용 로그인 구현

1. 로그인 구현 하기 위해 , 가져온 탬플릿의 Sign In 버튼 위치를 [검사]를 통해 찾는다.

2. vs code에서 해당 위치로 가서 button 에 효과주기 - onClick(클릭시)

<button id = "singInButton" onclick="signIn()">login</button>

3. 포스트맨 JQuiry이용하여 script 적용하기

1. 포스트맨을 활용하여

해당 API 의 코드스니펫 클릭 -> JavaScript- jQuery 로 설정하여 코드 복사

2. 복사한 코드를 vs code 에 login.html 파일 만든 후 맨 아래 script 부분의 signIn()에 붙여 넣는다.

function signIn(){
    
}

기입하여 이 사이에 복사한 코드를 넣는다.


function signIn(){
    var settings = {
  "url": "localhost:8080/api/users/login",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/json"
  },
  "data": JSON.stringify({
    "username": "member",
    "password": "member1234"
  }),
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
}

위의 onclick 버튼을 클릭하게 되면 "url": "localhost:8080/api/users/login"호출하게 된다.

3.웹에서 기입된 입력값을 가져오기 위해 jQuiry사용하여 값 가져온다.

$('#id').val();

3-1

입력창에 해당하는 입력값 id를 확인 후

3-2
vs code 에서 username 검색하여 위치를 파악 후 id값 한번 더 확인 후 스크립트에 아래 처럼 값을 변경해준다.

🎈id 값은 이 페이지에서 고유값이어야함 !

  "data": JSON.stringify({
    "username": $('#signInUsername').val(),
    "password": $('#signInPassword').val()
  }),
};

But 에러..?

"url": "http://localhost:8080/api/users/login" 형식으로 바꾸니 없었던 밑줄이 생기는 거 보니 이제 인식이 가능해진거 같다.

그 후에도 에러 발생하여 아래와 같이 문제 해결함
MIME type 에러 - 경로 설정 오류 해결

사전요청 & CORS ERROR

사전요청

  • 클라이언트가 이런요청 해도 되니? 라고 사전요청 하는 것으로 OPTION ~

웹컨피그에서 permit 처리 해줘야함 .

public class WebSecurityConfig implements WebMvcConfigurer { //인터페이스 

.authorizeHttpRequests()
        .antMatchers("/api/users/**").permitAll()
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() //옵션을 열어줘야 옵션으로 요청해서 그 응답을 주는 걸로 판단
        .anyRequest().authenticated()
        .and()
        .addFilterBefore(new JwtAuthFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);

    return http.build();

  }

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
					//메서드 허용
        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTION", "HEAD")
         //응답 헤더 허용
        .exposedHeaders("Authorization"); // 브라우저에서 클라이언트가 접근 가능한 응답 헤더 목록을 설정한다.
  }

[Spring boot X Spring Security] CORS 설정하기

.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() //옵션을 열어줘야 옵션으로 요청해서 그 응답을 주는 걸로 판단

**CORS error**

  • CORS(Cross-Origin Resource Sharing)는 웹 브라우저에서 특정 사이트(A.com) 로부터 다른 사이트(B.com) 로의 요청 및 접근을 가능하게 하는 프로토콜이다. 보안 상 최신 브라우저는 기본적으로 타 사이트로의 요청을 제한하고 있다. SPA 프레임워크의 사용 등으로 frontend 와 backend 의 분리가 일반적이 된 요즘, 서버로의 API 요청시 프로토콜/도메인/포트 등이 다르다면, CORS 설정이 올바르지 않다면 브라우저 콘솔에서 관련 error 를 마주하게 된다. 2.png 기본적인 CORS 요청들을 단순(simple) 요청이라 할 때, application/json 타입의 요청이거나 커스텀 헤더를 전송하는 등의 요청은 사전(preflight) 요청이라고 한다. 이 경우는 웹 브라우저에서 OPTIONS 메소드로 preflight(사전전달) 요청이 먼저 수행하고, 서버에서 허용 범주를 응답 받은 후에 실제 GET/POST 등의 요청을 보내게 된다. https://blog.kakaocdn.net/dn/sHxta/btrvBlNQOEK/SDJh0T1Tn7mmjpFCM1doR0/img.png

    CORS 서버 설정

    • 서버 개발자는 요청을 허용할 범주(Access-Control-Allow-* header/method/origin) 를 설정하여 응답 헤더에 보낼 수 있도록 세팅하면 된다. Spring Boot 의 경우, WebMvcConfigurer 를 구현하고 addCorsMappings 메소드를 오버라이드 하여 아래와 같이 설정할 수 있다.

      @Configurationpublic class WebConfig implements WebMvcConfigurer {
          @Overridepublic void addCorsMappings(CorsRegistry registry) {
              registry.addMapping("/**")
                      .allowedOrigins("http://localhost:3000", "http://localhost:8081")
                      .exposedHeaders("Authorization");//명시해줘야지만 헤더에서 토큰을 꺼낼 수 있음 
          }
      }
    • exposedHeaders 메소드의 경우

      브라우저에서 클라이언트가 접근 가능한 응답 헤더 목록을 설정한다. (Authorization 은 token 등을 이용할 때 많이 사용) cors mapping 만 설정했을 때는 GET, HEAD, POST 의 메소드에 대해서, 모든 출처의 요청에 대해 허용하는 것이 기본값이다. 위와 같이 Spring 에서 설정했을 경우, 아래와 같은 응답 헤더를 보내주고 CORS 는 성공하게 된다.

      Access-Control-Allow-Headers: content-typeAccess-Control-Allow-Methods: GET,HEAD,POSTAccess-Control-Allow-Origin: http://localhost:3000Access-Control-Expose-Headers: Authorization

      컨트롤러, 메소드 단위에서 @CrossOrigin 어노테이션을 사용할 수도 있다.

      또한, Spring Security 를 사용중이라면 아래와 유사한 방식으로 cors 요청을 처리할 수 있다.

📌 3.로그인 구현 후 JWT 토큰값 가져오기

로그인하고 이동하면서 jwt토큰 해더 가져가기

done(function안에 xhr안쓰면 아래꺼 작동 안하니 주의
localStorage.setItem('accessToken', xhr.getResponseHeader('Authorization'))
헤더에 온 jwt accesstoken을 가져와 http저장소에 저장

$.ajax(settings).done(function (response,status,xhr) {
  console.log(response);    //로그인 성공하면 
  console.log(xhr.getREsponseHeader('Authorization'))// 헤더에 있는 토큰을 받아와서
  localStorage.setItem('accessToken', xhr.getREsponseHeader('Authorization')) // 로컬스토리지 = 디비 , 에다가 셋 에 응답 받은 토큰을 그대로 넣는다
  alert('로그인 완료')
  window.location = '/index.html' //로그인 성공시 새로고침 
}).fail(function(response){
    console.log(response.responseJSON);
    if(response.responseJSON.statusCode === 404){
        alert('아이디와 비밀번호를 확인하여 주세요');
    } else{
        alert('서버에 문제가 발생하였습니다.');
    }
});
}
</script>

🎁 여기서 주의 . 아이디가 일치 하지 않습니다. 라는 에러메세지는 지양할것!
그럼 일치할때까지 빌런이 찾을수 있으므로
'아이디와 비밀번호를 확인하여 주세요' 로 지향 !

메인페이지 상단 " 님 반갑습니다. " 만들기

1.indext.html 에 있는

main.js로 이동하여

jQuery(document).ready(function($) {
있는데 이것의 역할은
//페이지 로딩 될때 실행됨
그래서 그 아래에
getUserMe(); 넣어
실행할때 실행시켜주겠다!라는 의미가 된다.

2. 맨 아래에 getUserMe();메소드 정의하기

포스트맨에서 고객프로필 요청 jquiry가져와서 붙이기

2-1 로컬스토리지에 셋팅한 값을 가져오는 코드를 기입한다.

"headers": {
"Authorization": localStorage.getItem("accessToken")
},

function getUserMe(){
	var settings = {
		"url": "http://localhost:8080/api/profile",
		"method": "GET",
		"timeout": 0,
		"headers": {
		  "Authorization": localStorage.getItem("accessToken")
		},
	  };
	  
	  $.ajax(settings).done(function (response) { //성공하면
		console.log(response);
		console.log(response.nickName); //닉네임이 
		$('#loginUser').empty(); // 기존 ..님 비우고 아래꺼 셋팅
		$('#loginUser').append(response.nickName + "님 반갑습니다.");
	  });
}

이름을 가져오기 위해 프로필을 가져오는 함수입니다.

프론트 팁

@RequestParam 으로 받은 값을 js 로 받아올때

 <script>
  function contactWrite(){
    var settings = {
      "url": "http://localhost:8080/api/managers/notices ?size = " + $('#id').val() + ""
      "method": "POST",
      "timeout": 0,

  
   ?size = " + $('#id').val() + ""

예)

var settings = {
  "url": "http://localhost:8080/t-exercise/selectboard/"+para[1],
  "method": "GET",
  "timeout": 0,

상대경로 , 절대경로 (/)찾아보기

  • 에러발생 : /index.html 을 해도 그 경로로 가지 않았다.

  • 원인 : 프로젝트 자체가 폴더 속에 있는데 폴더이름이 properties-main 이여서

    경로를 window.location./properties-main/index.html 하거나 아래와 같이 해줌

//window.location='/index.html'
}).fail(function(response){
  console.log(response)
});
}
  </script>
</html>

<!-- //상대경로 , 절대경로 (/)찾아보기

. 나 자신 
.. 나보다 한단계 위 ^^ -->
profile
개발자꿈나무

1개의 댓글

comment-user-thumbnail
2023년 2월 16일

cors에러 무섭습니다..... 하지만 의연하게 대처하시는 우리 혜원님!!
언제나 열심히하고 계신 모습을 보며 저도 다짐하곤 하지만 저는 혜원님의 새끼발가락도 못따라
가고 있네요 ㅎㅎㅎ

어느덧 프로젝트 2주차가되어 가는데 저도 혜원님도 지치지말고 조금 더 힘내봅시다!!
혜원님 언제나 밝은 에너지 주셔서 감사합니다 : >

답글 달기