어제부터 배포 하려고 하는데 
기존에는 war 파일을 배포해서  tomcat서버에서 실행하였는데요. 
이번엔 jar로 배포해서 spring boot를 이용해서 내부 서버로 실행 하려고 합니다.
지금 

@Autowired
private Environment env;

클래스에서 yml을 읽어오지 못하고 있거든요 
인텔리제이에선 

env is not null
spring.datasource.driver-class-name is not null
Driver class name: org.h2.Driver
spring.datasource.url: jdbc:h2:file:~/data/webDemo

문제 없이 읽어오는데요 
실제 프로그램 파워쉘을 이용해서 jar를 실행하면 

이런식으로 yml을 못읽어오거든요 yml은 현재 jar랑 동일한 위치에 있고 

java -jar webDemo.jar --spring.config.location=경로\application.yml

지정해서 실행해도 

datasource 위치를 못찾거든요 흠 좀더 찾아보겠습니다.
정 안되겠다 싶으면 장바구니 하던거 마무리 짓겠습니다.

테이블 BasketId 복합키고요 Baskets는 상품들이 장바구니에 들어가는 얘들이고요
status 상태에 따라 상태변경 하는데 아직 테스트는 안했습니다.
테스트는 내일 할수 있을까요.. 내일 회사에서 늦게올것같은데.. ㅠ 

status 장바구니 B, 삭제 D, 결재 C

테이블 


@Entity
@Table(name = "Baskets")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Baskets {

    @EmbeddedId
    private BasketId basketId;

    @NotEmpty
    @Column(name = "PRODUCT_NAME")
    private String productName;

    @NotNull
    private BigDecimal price;

    @NotEmpty
    @Column(name = "BIND_NUMBER")
    private String bindNumber;

    //status 장바구니 B, 삭제 D, 결재 C
    @NotEmpty
    @Column(name = "STATUS")
    private String status;

}

@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BasketId implements Serializable {

    @NotNull
    @Column(name = "PRODUCT_ID")
    private Long productId;

    @NotNull
    @Column(name = "USERS_ID")
    private Long usersId;

    @NotNull
    @Column(name = "date")
    private String date;

}

Model

@Repository
@Transactional
public class BasketsDao {
    @Autowired
    private EntityManagerFactory entityManagerFactory;

    //장바구니 리스트
    public List<Baskets> findAll(String userName, int page, int size) {
        List<Baskets> basketsList = null;
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

            CriteriaQuery<Baskets> criteriaQuery = criteriaBuilder.createQuery(Baskets.class);

            Root<Baskets> root = criteriaQuery.from(Baskets.class);

            // 복합키 검색 조건 생성
            Predicate compositeKeyPredicate = criteriaBuilder.and(
                    criteriaBuilder.equal(root.get("USERS_ID"), userName)
            );
            // 상태 검색 조건 생성
            Predicate statusPredicate = criteriaBuilder.equal(root.get("status"), "B");

            // 검색 조건 결합
            Predicate finalPredicate = criteriaBuilder.and(compositeKeyPredicate, statusPredicate);

            criteriaQuery.select(root);
            criteriaQuery.where(finalPredicate);

            TypedQuery<Baskets> typedQuery = entityManager.createQuery(criteriaQuery);
            typedQuery.setFirstResult((page - 1) * size);
            typedQuery.setMaxResults(size);
            
            basketsList = typedQuery.getResultList();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(entityManager!=null){
                entityManager.close();
            }
        }
        return basketsList;
    }

    //장바구니 등록
    public void save(Baskets baskets) {
        System.out.println("등록");
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            entityManager.getTransaction().begin();
            entityManager.persist(baskets);
            entityManager.getTransaction().commit();

        }catch (Exception e){
            entityManager.getTransaction().rollback();
            e.printStackTrace();
        }finally {
            if(entityManager!=null){
                entityManager.close();
            }
        }
    }

    //장바구니 삭제 및 결제
    //update로 처리
    public void update(String bindNumber,String status) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try{
            entityManager.getTransaction().begin();
            Baskets baskets = entityManager.find(Baskets.class, bindNumber);
            if (baskets != null) {
                baskets.setStatus(status);
                entityManager.merge(baskets);
                entityManager.getTransaction().commit();
                entityManager.refresh(baskets);
            } else {
                // 상품이 존재하지 않는 경우 예외 처리
                throw new IllegalArgumentException("Invalid product id: " + bindNumber);
            }
        }catch (Exception e){
            e.printStackTrace();
            entityManager.getTransaction().rollback();
        }finally {
            entityManager.close();
        }
    }

}

Service

@Service
public class BasketServiceImpl  implements BasketService {
    @Autowired
    BasketsDao basketsDao;
    //장바구니 담기
    public void save(Baskets baskets) {
        basketsDao.save(baskets);
    }
    //유저 장바구니 리스트 
    public List<Baskets> findAll(String userName, int page, int size) {
        return basketsDao.findAll(userName,page,size);
    }
    //상태 : 결제, 삭제, 장바구니 
    public void update(String bindNumber,String status) {
        basketsDao.update(bindNumber,status);
    }
}

Contoller 

@Controller
public class BasketController {
    @Autowired
    private BasketServiceImpl basketService;
    
    //장바구니 담기
    @GetMapping("/api/Baskets")
    @ResponseBody
    public List<Baskets> GetBaskets( int page,int size, HttpServletRequest request){
        List<Baskets> Baskets = null;
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {

            System.out.println("not success");
            // 세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return Baskets;
        }
       return basketService.findAll(session.getId(),page,size);
    }
    
    //유저 장바구니 리스트 
    @PostMapping("/Baskets/Post")
    public String PostBaskets(@RequestBody Baskets baskets, HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {

            System.out.println("not success");
            // 세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return "redirect:/fail";
        }
        basketService.save(baskets);
        System.out.println("baskets products");
        return "redirect:/index.html";
    }
    
   //상태 : 결제, 삭제, 장바구니 
    @PatchMapping("/api/Baskets/Patch/{BindNumber}/{Status}")
    public ResponseEntity<?> updatePatch(@PathVariable String BindNumber,@PathVariable String Status,HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {

            System.out.println("not success");
            // 세션에 사용자 정보가 없으면 로그인 페이지로 리다이렉트
            return ResponseEntity.badRequest().build();
        }
        try{
            basketService.update(BindNumber,Status);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseEntity.badRequest().build();
        }
        return ResponseEntity.ok().build();
    }
}

 

아직 테이블만 만들어둔 상태입니다.

복합키로 basket_id ,user_id,product_id를 이용할겁니다.


@Entity
@Table(name = "Baskets")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Baskets {

    @EmbeddedId
    private BasketId basketId;

    @NotEmpty
    @Column(name = "PRODUCT_NAME")
    private String productName;

    @NotNull
    private BigDecimal price;

}

@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BasketId implements Serializable {

    @Column(name = "ID")
    private Long id;

    @NotEmpty
    @Column(name = "PRODUCT_ID")
    private Long productId;

    @NotEmpty
    @Column(name = "USERS_ID")
    private Long usersId;

}

 

level 0 은 어드민이고

level  1은 고객 입니다.

차후 ui부분에서도 고객과 어드민을 나눠서 보여주도록 할겁니다.

vue는 조금 나중에 하도록 할거여서 좀더 spring쪽에 집중할겁니다.

내일은 물건들을 구매하거나 물건을 담는 장바구니를 구현할겁니다. 

로그인 프록시 컨트롤러 , 그리고 post 보안쪽으로 안전합니다. 

@PostMapping("/loginProxy")
    public String loginUser(@RequestBody Users usersData, HttpSession session){
        String hashedPassword=passwordEncoder.encode(usersData.getPassword());
        UserDetails userDetails = usersDetailService.loadUserByUsername(usersData.getUsername());
        if(passwordEncoder.matches(usersData.getPassword(),userDetails.getPassword())){
            Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            if (authentication.isAuthenticated()) {
                System.out.println(authentication.isAuthenticated());
                // 인증된 사용자 정보를 세션에 저장하거나 다른 처리를 수행할 수 있습니다.
                SecurityContextHolder.getContext().setAuthentication(authentication);
                session.setAttribute("user", userDetails);
                return "redirect:/index.html";
            }else{
                return "fail";
            }
        }else{
            return "fail";
        }
    }

현재 로그인하면 세션에 저장되고 로그아웃 버튼 클릭시 로그인세션에서 벗어납니다.

그리고 admin계정은 현재 어드민 페이지에 접속 가능하고요.

고객 계정을 만든후에 admin페이지에 들어가지 못하도록 할겁니다.

 

 

세션을 만들어서 접속 가능하도록 했고요

다음에는 어드민과 고객을 나눠서 페이지를 보이는것과 접속 위치를 다르게 확인할 예정입니다.

이전글:

2023.05.20 - [Spring] - spring vue 로그인session 03 -AuthenticationManager

 

spring vue 로그인session 03 -AuthenticationManager

음 지금 AuthenticationManager클래스까지는 지정했고요. 내일이나 모레쯤 마무리 지을수 있을것 같습니다. 이게 생각보다 sping 5.0대가 3.0떄랑 다르게 xml로 처리하는게 아니라 spring framework내에서 하려

kwaksh2319.tistory.com

보시면 그냥 페이지 접속시 403error가 발생하고 아이디와 비밀번호 db와 매칭이 되면 

session에 정보가 저장되어서 로그인이 되어  main페이지를 열어줍니다. 

UsersDetailService 코드 

@Service
public class UsersDetailService implements UserDetailsService {

    @Autowired
    private  UsersDao usersDao;
    public UsersDetailService(){

    }
    public UsersDetailService(UsersDao usersDao){
        this.usersDao=usersDao;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //유저 데이터 가져오기
        Users user = usersDao.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        } //user.getLevel()
        // 사용자 정보를 UserDetails 객체로 변환하여 반환user.getRoles()
        String role = "ROLE_ADMIN";
        if(user.getLevel()==0){
            role = "ROLE_ADMIN";
        }else if(user.getLevel()==1){
            role = "ROLE_CUSTOM";
        }else{
            role = "";
        }
        System.out.println(role);
        List<String> roles=new LinkedList<>();
        roles.add(role);

        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                getAuthorities(roles)
        );
    }

    private List<GrantedAuthority> getAuthorities(List<String> roles) {
        // 사용자의 권한(role) 정보를 GrantedAuthority 객체로 변환합니다.
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }
}

음 지금 AuthenticationManager클래스까지는 지정했고요. 내일이나 모레쯤 마무리 지을수 있을것 같습니다.
이전에는 xml로 처리했었는데요 요번에는 spring framework내에서 하려고하니 좀 많이 빡세네요 
계획은 어드민, 고객으로 나눌꺼고요 
session 로그인시 role_admin,role_custom으로 나눌예정입니다.
지금 계속 403 error가 나서 영상은 좀 나중에 올릴게요 
권한쪽 부여가 계속 잘 안되서 문제가 되고잇습니다.

빈등록 authenticationManager

 @Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    ....
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationProvider authenticationProvider) {
        return new CustomAuthenticationManager(authenticationProvider);
    }
    ....
  }

AuthenticationManager 클래스를 longinController에 객체 생성을 했습니다.

@Controller
public class loginController {
...
    @Autowired
    private AuthenticationManager authenticationManager;
...
}

 
 

기존에 webSecurityConfigurerAdapter가 굉장히 많은 역할을 해줬다는게 좀 느껴지네요.

Field authenticationManager in kr.co.kshproject.webDemo.interfaces.loginController required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.

에러가나는데 지금 아래와 같이 변경해서 작업중인데 에러가 나는군요 ㅠ webSecurityConfigurerAdapter가 그립네요 ㅎ ㅠ 퇴근하고 공부하는거라 많이 시간이 안나오네요 이번주 주말까지해서 회원가입시 SHA 256이용해서 비밀번호 변경하고 session을 이용해서 웹페이지마다 관리자가 이용하는 페이지 고객이 이용하는 페이지로 만들겁니다.

package kr.co.kshproject.webDemo.Common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    @Lazy
    private AuthenticationProvider myAuthenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers().permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/Main")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll();

        http.authenticationProvider(myAuthenticationProvider);

        return http.build();
    }
    @Configuration
    protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {

        @Autowired
        private AuthenticationProvider myAuthenticationProvider;

        @Override
        public void init(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(myAuthenticationProvider);
        }
    }

    @Bean
    public AuthenticationProvider myAuthenticationProvider() {
        return new MyAuthenticationProvider();
    }

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

+ Recent posts