Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
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
Archives
Today
Total
관리 메뉴

JAVA Developer Training

38. Spring (상품,멤버를 이용한 sellerController) 본문

트레이닝

38. Spring (상품,멤버를 이용한 sellerController)

Romenest 2021. 10. 6. 16:31

1. jwtUtil (토큰 관련 기능)

package com.example.jwt;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import org.springframework.stereotype.Service;

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

// 토큰발행 (만료시간) , 토큰의 유효성 검사, 토큰과 관련된 메소드
@Service
public class JwtUtil {

    // 토큰 생성용 보안키
    private final String SECRETKEY = "fekjkfe43jfe";

    // 정보 추출용 메소드
    private <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = Jwts.parser().setSigningKey(SECRETKEY).parseClaimsJws(token).getBody();
        return claimsResolver.apply(claims);
    }

    // 토큰 생성(아이디 정보를 이용한 토큰 생성)
    public String generateToken(String username) {
        // 2021-09-30 09:47:50.034 => 1234567890 => 1234567890123
        // long tokenValidTime = 1000 * 60 * 30; //30분
        long tokenValidTime = 1000 * 60 * 60 * 4; // 4시간

        Map<String, Object> claims = new HashMap<>();
        String token = Jwts.builder().setClaims(claims).setSubject(username)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + tokenValidTime))
                .signWith(SignatureAlgorithm.HS256, SECRETKEY).compact();

        return token;
    }

    // 토큰 유효성 확인
    // vue에서 오는 토큰에서 꺼낸 아이디 정보와
    // 시큐리티 세션에 보관되어 있던 아이디 정보
    public Boolean validateToken(String token, String userid) {
        // 토큰에서 아이디 정보 추출
        final String username = this.extractUsername(token);

        if (username.equals(userid) && !isTokenExpired(token)) {
            return true;
        }
        return false;
    }

    // 토큰에서 아이디 정보 추출하기
    public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    // 토큰에서 만료 시간 추출하기
    public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    // 토큰의 만료시간이 유효한지 확인
    public Boolean isTokenExpired(String token) {
        // 만료시간 가져와서 현재시간보다 이전인지 확인
        return this.extractExpiration(token).before(new Date());
    }
    

}

2.jwtRequestFilter 인증서가 유효하면 컨트롤러로 진입

package com.example.jwt;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.example.service.MemberDetailsService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

//nodejs checkToken
//인증서가 유효하면 컨트롤러로 진입함
@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    MemberDetailsService mService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            // 넘어오는것이 request
            // const headers = {"Content-Type" : "application/json" ,"token" : 'aaaa'}
            String token = request.getHeader("token");

            // 임시
            String username = null;

            if (token != null) {
                // 실제토큰
                username = jwtUtil.extractUsername(token);
            }

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

                // 시큐리티에 로그인 처리루틴
                UserDetails userDetails = mService.loadUserByUsername(username);

                if (jwtUtil.validateToken(token, userDetails.getUsername())) {
                    UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(userDetails,
                            null, userDetails.getAuthorities());

                    upat.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

                    SecurityContextHolder.getContext().setAuthentication(upat);
                }
            }
            // 토큰 유무와 관련없이 컨트롤러로 넘겨
            // 컨트롤러로 넘어가는 시점
            // next (req,res)
            filterChain.doFilter(request, response);

        } catch (Exception e) {
            response.sendError(578, "토큰오류");
        }
    }
}

3. 권한 설정 SecurityConfig

package com.example.security;

import com.example.jwt.JwtRequestFilter;
import com.example.service.MemberDetailsService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;

import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //새로운 기능을 추가한 DetailsService사용
    @Autowired
    MemberDetailsService mService;

    //환경설정에서 객체만들기
    //회원가입시 암호방식을 로그인시 같은 방식으로 적용해야 하기 때문에
    @Bean
    public BCryptPasswordEncoder encode(){
        return new BCryptPasswordEncoder();
    }

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    //인증박식은 MemberDetailsService를 사용하고, 암호화방식은
    //위에만든 @Bean객체 방식으로 사용
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(mService).passwordEncoder(encode());
    }

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //권한 추가
        http.authorizeRequests().antMatchers("/admin","/admin/*").hasAnyRole("ADMIN").anyRequest().permitAll();

        //필터 추가
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        //session 저장방법
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        //h2-console 사용
        //127.0.0.1:8080/REST/h2-console
        http.csrf().disable();
        http.headers().frameOptions().sameOrigin();
    }
    
}

4.SellorController

package com.example.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.entity.Item;
import com.example.entity.Member;
import com.example.jwt.JwtUtil;
import com.example.service.ItemServiceImpl;
import com.example.service.MemberService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

    @Autowired
    MemberService mService;

    @Autowired
    ItemServiceImpl iService;

    @Autowired
    JwtUtil jwtUtil;

    // 127.0.0.1:8080/REST/api/seller/item_delete
    // [{"name":"a", "content":"b", "price":"c","quantity":"d"},{},{},{}....]
    @RequestMapping(value = "/seller/item_delete", method = {
            RequestMethod.DELETE }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    // @ModelAttribute List<Item> list = 한번에 해결하는방법
    public Map<String, Object> itemDeletePOST(@RequestBody List<Item> list, @RequestHeader("token") String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            // 판매자 이메일 가져오기
            String email = jwtUtil.extractUsername(token);
            for (Item item : list) {
                Member member = mService.getMemberOne(email);
                item.setMember(member);
            }
            iService.deleteBatch(list);
            map.put("status", 200);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }

    // 127.0.0.1:8080/REST/api/seller/item_update
    // [{"name":"a", "content":"b", "price":"c","quantity":"d"},{},{},{}....]
    @RequestMapping(value = "/seller/item_update", method = {
            RequestMethod.PUT }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    // @ModelAttribute List<Item> list = 한번에 해결하는방법
    public Map<String, Object> itemUpdatePUT(@RequestBody List<Item> list, @RequestHeader("token") String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            // 판매자 이메일 가져오기
            String email = jwtUtil.extractUsername(token);
            for (Item item : list) {
                Member member = mService.getMemberOne(email);
                item.setMember(member);
            }
            iService.updateBatch(list);
            map.put("status", 200);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }

    // 127.0.0.1:8080/REST/api/seller/item_insert
    // [{"name":"a", "content":"b", "price":"c","quantity":"d"},{},{},{}....]
    @RequestMapping(value = "/seller/item_insert", method = {
            RequestMethod.POST }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    // @ModelAttribute List<Item> list = 한번에 해결하는방법
    public Map<String, Object> itemInsertPost(@RequestParam("name") String[] name,
            @RequestParam("content") String[] content, @RequestParam("price") Long[] price,
            @RequestParam("quantity") Long[] quantity,

            @RequestHeader("token") String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            // 판매자 이메일 가져오기
            String email = jwtUtil.extractUsername(token);

            // 위에서 받은 값을 list로 변환
            List<Item> list = new ArrayList<Item>();
            for (int i = 0; i < name.length; i++) {
                Item item = new Item();
                item.setName(name[i]);
                item.setContent(content[i]);
                item.setPrice(price[i]);
                item.setQuantity(quantity[i]);

                Member member = mService.getMemberOne(email);
                item.setMember(member);
                list.add(item);
            }
            // 일괄추가
            iService.insertBatch2(list);
            map.put("status", 200);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }

    // 127.0.0.1:8080/REST/api/seller/item_insert
    // [{"name":"a", "content":"b", "price":"c","quantity":"d"},{},{},{}....]
    @RequestMapping(value = "/seller/item_insert1", method = {
            RequestMethod.POST }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    // @ModelAttribute List<Item> list = 한번에 해결하는방법
    public Map<String, Object> itemInsert1Post(@RequestBody List<Item> list, @RequestHeader("token") String token) {
        Map<String, Object> map = new HashMap<>();
        try {
            // 판매자 이메일 가져오기
            String email = jwtUtil.extractUsername(token);
            for (Item item : list) {
                Member member = mService.getMemberOne(email);
                item.setMember(member);
            }
            iService.insertBatch2(list);
            map.put("status", 200);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }

    // 127.0.0.1:8080/REST/api/seller/item_select
    @RequestMapping(value = "/seller/item_select", method = {
            RequestMethod.GET }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> itemSelectGET(@RequestParam("no") Long no) {
        Map<String, Object> map = new HashMap<>();
        try {
            Item item = iService.selectItemOne(no);
            map.put("status", 200);
            map.put("item", item);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }

    // 127.0.0.1:8080/REST/api/seller/item_select_list
    @RequestMapping(value = "/seller/item_select_list", method = {
            RequestMethod.GET }, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String, Object> itemSelectListGET() {
        Map<String, Object> map = new HashMap<>();
        try {
            List<Item> item = iService.selectItemList();
            map.put("status", 200);
            map.put("item", item);
        } catch (Exception e) {
            map.put("status", e.hashCode());
        }
        return map;
    }
}