BJSNuruhee / levelup

0 stars 0 forks source link

[SpringBoot] JWT 설정 #31

Closed yejun95 closed 10 months ago

yejun95 commented 10 months ago

SpringBoot + JWT

✔ dependency 설정

             <!-- JJWT API  : DatatypeConverter 사용-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.2</version>
        </dependency>

        <!-- JJWT Implementation : Jwts 사용 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.2</version>
        </dependency>

        <!-- JJWT Jackson : Jwts 사용 -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.2</version>
        </dependency>




✔ JwtService

package com.example.demo.jwt;

import java.security.Key;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.springframework.stereotype.Service;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Service
public class JwtService {
    // 비밀키 생성
    private static final String SECRET_KEY = "asafdasdfajijoijfiajoijawoiejfiojijojiefiowjef";

    // 토큰 구현 메서드
    public String createToken(String subject, long expTime) {
        if(expTime <= 0) {
            throw new RuntimeException("만료 시간은 0보다 커야함");
        }

        // 시그니처 알고리즘 선택
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 스트링 형태의 key를 바이트 단위의 key로 변환
        // jaxb-api : DatatypeConverter
        byte[] secretkeyBytes = DatatypeConverter.parseBase64Binary(SECRET_KEY);

        // signing key 생성
        // SecretKeySpec = 자바에서 제공하는 암호화 키를 만드는 객체
        Key signingkey = new SecretKeySpec(secretkeyBytes, signatureAlgorithm.getJcaName());

        // 생성한 key 리턴
        return Jwts.builder()
                .setSubject(subject) // 유저 아이디
                .signWith(signingkey, signatureAlgorithm) // key와 알고리즘
                .setExpiration(new Date(System.currentTimeMillis() + expTime)) // 현재 시간설정
                .compact(); // build 마무리 
    }

    // 토큰을 boolean 으로 검증
    // 아래 로직에서는 subject 값을 확인하기 위해 String 설정
    public String getSubject(String token) {
        // plyload에 key, value 지정
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET_KEY))
                .build()
                .parseClaimsJws(token) // 토큰을 넣어 디코딩
                .getBody(); // 데이터를 body로 받는다. (claim이 만들어진다)

        return claims.getSubject(); // 토큰의 subject 값을 가져온다. (= 유저아이디)
    }

}




✔ controller

package com.example.demo.controller;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.entity.User;
import com.example.demo.jwt.JwtService;
import com.example.demo.mapper.UserMapper;

@RestController
@RequestMapping(value = "/api")
public class UserController {

    @Autowired
    UserMapper userMapper;

    @Autowired
    JwtService jwtService;

    // JWT 로그인 기능 구현
    @PostMapping("/post/user/jwtLogin")
    public Map<String, Object> memJWTLogin(@RequestBody User vo) {
        User mvo = userMapper.memLogin(vo);
        if(mvo != null) { // 로그인 성공
            // 토큰 생성 (유저 아이디, 만료 시간 2분)
            String token = jwtService.createToken(vo.getUserId(), (2*1000*60));

            // 리턴할 map
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("result", token);
            return map;
        } else {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("result", "bad");
            return map;
        }
    }

    // 생선한 JWT 토큰 조회하기
    @GetMapping("/get/subject")
    public Map<String, Object> getSubject(@RequestParam(value = "token") String token) {
        String subject = jwtService.getSubject(token);

        // 리턴할 map
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("result", subject);
        return map;
    }
}

로그인 성공 image

로그인 실패 image

생성한 토큰을 확인 get 요청

image



Reference

유튜브 성지채널 : SpringBoot 에서 JWT를 활용한 인증 구현하기