티스토리 뷰

반응형

52,53 jwt

  json web tokens: json 형식으로 만드는  웹토큰, access token 을 좀더 잘 사용해보자. 많은 정보를 담을 수 있다.

 

 

* 구성

header :  json 타입, 무슨 알고리즘인지,,, 등..

payload  : jwt 에  포함한 정보들 . 암호화가 안돼서 외부에 유출되면 아노디는 정보를 담으면 안된다.

signature :  이 토큰이 만료되지 않았음 증명 (암호화된 방식의 서명) 

( 이 각각은 header. payload. 등 마침표를 이용해서 연결이 된다.) 

이 정보들은 json 포맷인데 이대로 나가면 안되기 때문에 base64 url encoding 을 통해  감싸 일정한 문자열 형태로  나가게 된다.

payload 에 담기는 데이터는 우리는 claim 이라고 부르는데,  복수여서 claims 라고 부른다.  여기에 유저 아이디, 사용자 이름 등이 포함되게 된다. 가능하면 여기에 많은 정보를 담지 않는 것이 좋다.  토큰이 유효한 기간을 담는 것이 좋다.

 

signiture

우리의 데이터가 위변조 되지 않았음을 서명한다. 해싱(HAMX- SHA256 : HS256)하고  나중에 값이 바뀌지 않았는지 확인하는데 쓰임. 이런 서명을 할때, 비밀키를 사용하는데, 비밀키는 노출되지 않아야함( 다른 사람이 이 키를 가지고 똑같이 위변조 가능함) 

 

 


jwt.io

 

제일많이 쓰이는 자바 라이브러리는 jjwt

 

 

 

 

 

 

설치

implementation 'io.jsonwebtoken:jjwt-api:0.10.7'
runtime 'io.jsonwebtoken:jjwt-impl:0.10.7'
runtime 'io.jsonwebtoken:jjwt-jackson:0.10.7'

여기에 이런식으로 지정을 해놓고, (주기적으로 바꿔주면 좀더 안전하게 사용 가능)

  //application.yml
  jwt:
    secret: 비밀이비밀비밀해

 

package kr.co.fastcampus.eatgo;

import kr.co.fastcampus.eatgo.filters.JwtAuthenticationFilter;
import kr.co.fastcampus.eatgo.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.servlet.Filter;

@Configuration
@EnableWebSecurity
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {

    @Value("${jwt.secret}") //application.yml 에서 지정한 값을 이런식으로 불러올 수 있다.
    private String secret;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        Filter filter = new JwtAuthenticationFilter(
                authenticationManager(), jwtUtil());

        http
                .cors().disable()
                .csrf().disable()
                .formLogin().disable()
                .headers().frameOptions().disable()
                .and()
                .addFilter(filter)
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtUtil jwtUtil() {
        return new JwtUtil(secret);
    }

}
package kr.co.fastcampus.eatgo.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.security.Key;

public class JwtUtil {

    private Key key;

    public JwtUtil(String secret) {
        this.key = Keys.hmacShaKeyFor(secret.getBytes());
    }

    public String createToken(Long userId, String name, Long restaurantId) {
        JwtBuilder builder = Jwts.builder()
                .claim("userId", userId)
                .claim("name", name);
        if (restaurantId != null) {
            builder = builder.claim("restaurantId", restaurantId);
        }
        return builder
                .signWith(key, SignatureAlgorithm.HS256)//32 글자 이상이여야한다.
                .compact();
    }

    public Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(token)
                .getBody();
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

바 인강이 듣고 싶다면 =>https://bit.ly/3ilMbIO

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
29 30 31
글 보관함