Spring boot을 사용하여 JWT 인증 API 만들기

107943 단어 springbootjwtapijava
사랑하는 여러분,
오늘은 Spring Boot을 사용하여 JWT 인증을 받은 간단한 RESTAPI를 만드는 방법을 소개합니다.
너는 아마 나의 이전 블로그 글을 보고 싶을 것이다
저는 위의 블로그 글에서 MySQL을 설정하는 방법, IntelliJ에서 새로운 프로젝트를 만드는 방법을 소개했기 때문에 이 블로그에서 이 부분을 건너뛰겠습니다.
0. SQL 쿼리를 사용하여 MySQL 데이터베이스 및 테이블을 만듭니다.
  • 새 데이터베이스 만들기
  • CREATE DATABASE restapi;
    USE restapi;
    
  • 블로그를 위한 새 표 만들기
  • CREATE TABLE blog (
      id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      title VARCHAR(500) NOT NULL,
      content VARCHAR(5000) NOT NULL
    );
    
  • userinfo에 대한 새 테이블을 만듭니다.
  • CREATE TABLE user_info(
      id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
      username VARCHAR(50) NOT NULL,
      password VARCHAR(500) NOT NULL,
      fullname VARCHAR(50) NOT NULL
    );
    
    1. 본 강좌에 필요한 의존 항목:
    
    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.8.RELEASE</version>
        </parent>
    
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-core</artifactId>
                <version>5.1.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <version>5.1.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>5.1.6.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>
        </dependencies>
    
    
    
    REST API를 만들려면 spring boot starter가 필요합니다.
    Mysql 연결기 자바, Mysql 데이터베이스 연결에 사용.
    Spring Security 인증 설정
    JWT 사용 권한을 부여하는 jsonwebtoken
    2. 프로젝트 구조
  • 리소스:
    우리는 응용 프로그램에서 항목의 속성을 정의할 것이다.속성
  • 
    spring.datasource.url=jdbc:mysql://localhost:3306/restapi
    spring.datasource.username=xxxx
    spring.datasource.password=xxxx
    spring.datasource.platform=mysql
    jwt.secret={bcrypt}$donald
    
    
    봄.데이터베이스 정보를 제공하는 데이터 원본입니다.사용자 이름과 비밀번호를 제공해야만 일을 할 수 있습니다.
    jwt.secret은 jwt의 키입니다.(이따가 자세히 논의할게요)
  • 패키지:
  • +) 구성:
    항목을 저장하기 위한 프로필입니다.
    +) 컨트롤러:
    인증용 컨트롤러 클래스, 블로그 컨텐츠를 정의하는 CRUD, 새 사용자 만들기
    +) 예외:
    검증 데이터의 기본 오류 핸들과 이상 정의
    +) 모델:
    Blog 엔티티, UserInfo 엔티티, JwtRequest 및 JwtResponse에 대한 모델 만들기
    +) 저장소:
    JPA와 MySQL 데이터베이스를 사용하여 블로그 및 UserInfo 저장소 만들기
    +) 서비스:
    데이터베이스에 사용자 이름이 있는지 확인하기 위해 JwtUserDetails Service 만들기
  • SpringBoot Application을 실행하는 기본 애플리케이션 클래스:
  • 
    @SpringBootApplication
    public class MainApplicationClass {
    
    
        public static void main(String[] args) {
            SpringApplication.run(MainApplicationClass.class, args);
        }
    
    }
    
    
    3. 우리는 무엇을 창조할 것인가:
  • 어플리케이션에서 새 사용자 만들기 API
  • 사용자 자격 증명이 유효한지 확인하는 데 사용되는 API이며, 반환 영패인 경우 다른 작업을 수행할 수 있습니다
  • 새 블로그 글을 만들거나 블로그 글을 보거나 업데이트하는 데 사용되는 API입니다.
  • 따라서 자격 증명을 작성하고 검증하는 데 사용되는 API는 권한 부여 섹션 -->이 없으므로 누구나 액세스하고 이러한 API를 실행할 수 있습니다.
    블로그와 상호작용하는 API는 jwt 영패를 사용하여 인증을 해야 합니다.
    이렇게 하려면 config 패키지의 WebSecurity 구성 클래스에서 configure 방법을 만들어야 합니다.
    
    httpSecurity.csrf().disable()
    
                    .authorizeRequests().antMatchers("/authenticate","/user").permitAll().
    
            anyRequest().authenticated().and().
    
            exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
    
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    
    
    
    4. jwt 영패 설정
    JwtAuthenticationEntry Point는 사용자 자격 증명이 올바르지 않을 때 인증되지 않은 메시지를 표시합니다.
    
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.Serializable;
    
    public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
    
        private static final long serialVersionUID = -7858869558953243875L;
    
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
    
                             AuthenticationException authException) throws IOException {
    
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    
        }
    
    }
    
    
    JwtRequestFilter 필터링 헤더 값:
    
    import donald.apiwithspringboot.service.JwtUserDetailsService;
    import io.jsonwebtoken.ExpiredJwtException;
    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;
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    @Component
    public class JwtRequestFilter extends OncePerRequestFilter {
    
    
        @Autowired
        private JwtUserDetailsService jwtUserDetailsService;
    
        private final JwtToken jwtTokenUtil;
    
        public JwtRequestFilter(JwtToken jwtTokenUtil) {
            this.jwtTokenUtil = jwtTokenUtil;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
    
                throws ServletException, IOException {
    
            final String requestTokenHeader = request.getHeader("Authorization");
    
            String username = null;
    
            String jwtToken = null;
    
    
            if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
    
                jwtToken = requestTokenHeader.substring(7);
    
                try {
    
                    username = jwtTokenUtil.getUsernameFromToken(jwtToken);
    
                } catch (IllegalArgumentException e) {
    
                    System.out.println("Unable to get JWT Token");
    
                } catch (ExpiredJwtException e) {
    
                    System.out.println("JWT Token has expired");
    
                }
    
            } else {
    
                logger.warn("JWT Token does not begin with Bearer String");
    
            }
    
    
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
    
                UserDetails userDetails = this.jwtUserDetailsService.loadUserByUsername(username);
    
    
                if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
    
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
    
                            userDetails, null, userDetails.getAuthorities());
    
                    usernamePasswordAuthenticationToken
    
                            .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
    
    
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
            chain.doFilter(request, response);
        }
    }
    
    
    jwt 영패를 생성하는 데 사용되는 JwtToken 클래스:
    @Component
    public class JwtToken implements Serializable {
    
        private static final long serialVersionUID = -2550185165626007488L;
    
        public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60;
    
        @Value("${jwt.secret}")
        private String secret;
    
    
        public String getUsernameFromToken(String token) {
    
            return getClaimFromToken(token, Claims::getSubject);
    
        }
    
    
        public Date getExpirationDateFromToken(String token) {
    
            return getClaimFromToken(token, Claims::getExpiration);
    
        }
    
        public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
    
            final Claims claims = getAllClaimsFromToken(token);
    
            return claimsResolver.apply(claims);
    
        }
    
    
        private Claims getAllClaimsFromToken(String token) {
    
            return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    
        }
    
    
        private Boolean isTokenExpired(String token) {
    
            final Date expiration = getExpirationDateFromToken(token);
    
            return expiration.before(new Date());
    
        }
    
    
        public String generateToken(UserDetails userDetails) {
    
            Map<String, Object> claims = new HashMap<>();
    
            return doGenerateToken(claims, userDetails.getUsername());
    
        }
    
    
        private String doGenerateToken(Map<String, Object> claims, String subject) {
    
            return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
    
                    .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
    
                    .signWith(SignatureAlgorithm.HS512, secret).compact();
    
        }
    
    
        public Boolean validateToken(String token, UserDetails userDetails) {
    
            final String username = getUsernameFromToken(token);
    
            return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    
        }
    
    }
    
    
    
    WebSecurityConfig는 우리가 필요로 하는 bean을 정의하고 인증 구성 경로를 사용합니다.
    
    import donald.apiwithspringboot.service.JwtUserDetailsService;
    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.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    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.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    
        @Autowired
        private JwtUserDetailsService jwtUserDetailsService;
    
        @Autowired
        private JwtRequestFilter jwtRequestFilter;
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    
            auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
    
        }
    
        @Bean
        public JwtAuthenticationEntryPoint jwtAuthenticationEntryPointBean() throws Exception{
            return new JwtAuthenticationEntryPoint();
        }
    
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
    
        }
    
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
    
            httpSecurity.csrf().disable()
    
                    .authorizeRequests().antMatchers("/authenticate","/user").permitAll().
    
            anyRequest().authenticated().and().
    
            exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
    
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    
        }
    
    }
    
    
    
    5, 컨트롤러:
    AuthController는 사용자 자격 증명을 검증하기 위해 API를 정의하고 jwt 영패에 올바르게 응답합니다.
    
    import donald.apiwithspringboot.model.JwtRequest;
    import donald.apiwithspringboot.model.JwtResponse;
    import donald.apiwithspringboot.service.JwtUserDetailsService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.authentication.BadCredentialsException;
    import org.springframework.security.authentication.DisabledException;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.web.bind.annotation.*;
    import donald.apiwithspringboot.config.JwtToken;
    import org.springframework.security.authentication.AuthenticationManager;
    
    @RestController
    @CrossOrigin
    public class AuthController {
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private JwtToken jwtToken;
    
        @Autowired
        private JwtUserDetailsService jwtUserDetailsService;
    
    
        @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
        public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {
    
    
            authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword());
    
            final UserDetails userDetails = jwtUserDetailsService
    
                    .loadUserByUsername(authenticationRequest.getUsername());
    
            final String token = jwtToken.generateToken(userDetails);
    
            return ResponseEntity.ok(new JwtResponse(token));
    
        }
    
        private void authenticate(String username, String password) throws Exception {
    
            try {
    
                authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
    
            } catch (DisabledException e) {
    
                throw new Exception("USER_DISABLED", e);
    
            } catch (BadCredentialsException e) {
    
                throw new Exception("INVALID_CREDENTIALS", e);
    
            }
    
        }
    
    }
    
    
    새 블로그 만들기, 블로그 내용 수정, 블로그 보기 또는 업데이트를 위한 API 작성을 위한 BlogController 클래스
    
    
    import donald.apiwithspringboot.model.Blog;
    import donald.apiwithspringboot.repository.BlogRepository;
    import org.springframework.web.bind.annotation.*;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    public class BlogController {
    
        final
        private BlogRepository blogRepository;
    
        public BlogController(BlogRepository blogRepository) {
            this.blogRepository = blogRepository;
        }
    
        @GetMapping("/blog")
        public List<Blog> index(){
            return blogRepository.findAll();
        }
    
        @GetMapping("/blog/{id}")
        public Blog show(@PathVariable String id){
            int blogId = Integer.parseInt(id);
            return blogRepository.findById(blogId).orElse(new Blog());
        }
    
        @PostMapping("/blog/search")
        public List<Blog> search(@RequestBody Map<String, String> body){
            String searchTerm = body.get("text");
            return blogRepository.findByTitleContainingOrContentContaining(searchTerm, searchTerm);
        }
    
        @PostMapping("/blog")
        public Blog create(@RequestBody Map<String, String> body){
            String title = body.get("title");
            String content = body.get("content");
            return blogRepository.save(new Blog(title, content));
        }
    
        @PutMapping("/blog/{id}")
        public Blog update(@PathVariable String id, @RequestBody Map<String, String> body){
            int blogId = Integer.parseInt(id);
            // getting blog
            Blog blog = blogRepository.findById(blogId).orElse(new Blog());
            blog.setTitle(body.get("title"));
            blog.setContent(body.get("content"));
            return blogRepository.save(blog);
        }
    
        @DeleteMapping("blog/{id}")
        public boolean delete(@PathVariable String id){
            int blogId = Integer.parseInt(id);
            blogRepository.deleteById(blogId);
            return true;
        }
    
    }
    
    UserInfoController는 새 사용자를 만들고 암호를 사용하여 데이터베이스에 삽입하고 BCryptPasswordEncoder 인코딩을 사용합니다.
    import donald.apiwithspringboot.exceptions.ValidationException;
    import donald.apiwithspringboot.model.UserInfo;
    import donald.apiwithspringboot.repository.UserInfoRepository;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    import java.security.NoSuchAlgorithmException;
    import java.util.Map;
    
    @RestController
    public class UserInfoController {
    
    
        final
        private UserInfoRepository userInfoRepository;
    
    //    private HashData hashData = new HashData();
    
        public UserInfoController(UserInfoRepository userInfoRepository) {
            this.userInfoRepository = userInfoRepository;
        }
    
    
        @PostMapping("/user")
        public Boolean create(@RequestBody Map<String, String> body) throws NoSuchAlgorithmException {
            String username = body.get("username");
            if (userInfoRepository.existsByUsername(username)){
    
                throw new ValidationException("Username already existed");
    
            }
    
            String password = body.get("password");
            String encodedPassword = new BCryptPasswordEncoder().encode(password);
    //        String hashedPassword = hashData.get_SHA_512_SecurePassword(password);
            String fullname = body.get("fullname");
            userInfoRepository.save(new UserInfo(username, encodedPassword, fullname));
            return true;
        }
    
    }
    
    
    
    6. 예외적인 경우:
    BaseErrorHandles 클래스의 handleException은 BAD\u 요청입니다.
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @ControllerAdvice
    @Slf4j
    public class BaseErrorHandles {
    
        @ResponseBody
        @ExceptionHandler(value = ValidationException.class)
        public ResponseEntity<?> handleException(ValidationException exception) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exception.getMsg());
        }
    }
    
    
    유효성 검사 예외
    
    public class ValidationException extends RuntimeException {
    
        private static final long serialVersionUID = 1L;
        private String msg;
    
        public ValidationException(String msg) {
            this.msg = msg;
        }
    
        public String getMsg() {
            return msg;
        }
    
    }
    
    
    7, 모델:
    블로그 모델: 블로그 실체 정의
    @Entity
    public class Blog {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        private String title;
        private String content;
    
        public Blog() {  }
    
        public Blog(String title, String content) {
            this.setTitle(title);
            this.setContent(content);
        }
    
        public Blog(int id, String title, String content) {
            this.setId(id);
            this.setTitle(title);
            this.setContent(content);
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        @Override
        public String toString() {
            return "Blog{" +
                    "id=" + id +
                    ", title='" + title + '\'' +
                    ", content='" + content + '\'' +
                    '}';
        }
    
    }
    
    
    UserInfo enty를 정의하는 데 사용되는 UserInfo 클래스:
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    @Entity
    public class UserInfo {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        private String username;
        private String password;
        private String fullname;
    
        public UserInfo() {
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public UserInfo(String username, String password, String fullname) {
            this.username = username;
            this.password = password;
            this.fullname = fullname;
        }
    
        public String getFullname() {
            return fullname;
        }
    
        public void setFullname(String fullname) {
            this.fullname = fullname;
        }
    }
    
    
    
    AuthController에서 요청된 사용자 이름과 암호를 검증하는 데 사용되는 JwtRequest 모델
    
    public class JwtRequest implements Serializable {
    
        private static final long serialVersionUID = 5926468583005150707L;
    
        private String username;
    
        private String password;
    
        public JwtRequest()
    
        {
    
        }
    
        public JwtRequest(String username, String password) {
    
            this.setUsername(username);
    
            this.setPassword(password);
    
        }
    
        public String getUsername() {
    
            return this.username;
    
        }
    
        public void setUsername(String username) {
    
            this.username = username;
    
        }
    
        public String getPassword() {
    
            return this.password;
    
        }
    
        public void setPassword(String password) {
    
            this.password = password;
    
        }
    
    }
    
    
    
    JwtResponse 영패 응답을 위한 모델 만들기
    
    
    import java.io.Serializable;
    
    public class JwtResponse implements Serializable {
    
        private static final long serialVersionUID = -8091879091924046844L;
    
        private final String jwttoken;
    
        public JwtResponse(String jwttoken) {
    
            this.jwttoken = jwttoken;
    
        }
    
        public String getToken() {
    
            return this.jwttoken;
    
        }
    
    }
    
    
    8. 저장소:
    BlogRepository는 JPA for blog 테이블을 통해 MySQL 데이터베이스와 협업합니다.
    
    @Repository
    public interface BlogRepository extends JpaRepository<Blog,Integer> {
    
        // custom query to search to blog post by title or content
        List<Blog> findByTitleContainingOrContentContaining(String text, String textAgain);
    
    }
    
    
    UserInfoRepository는 JPA를 통해 MySQL 데이터베이스를 user\u info 테이블로 처리합니다.
    
    @Repository
    public interface UserInfoRepository extends JpaRepository<UserInfo,Integer> {
    
        Boolean existsByUsername(String username);
        UserInfo findByUsername(String username);
    
    
    }
    
    
    9. 서비스:
    loadUserByUsername 메서드에 대한 JwtUserDetails Service 정의:
    
    @Component
    public class JwtUserDetailsService implements UserDetailsService {
    
        @Autowired
        private UserInfoRepository userInfoRepository;
    
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
            UserInfo user = userInfoRepository.findByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException("User not found with username: " + username);
            }
            return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                    new ArrayList<>());
        }
    
    }
    
    
    10. spring boot 응용 프로그램을 실행합니다.
    단순 실행: mvn spring boot:run
    11. Postman을 사용하여 API와 상호 작용:
    새 사용자 만들기

    새 사용자를 생성했습니다.

    사용자 자격 증명 확인:

    사용자 자격 증명 확인 성공:

    새 블로그 요청 본문:

    새 블로그 제목 만들기:

    새 블로그 응답 만들기:

    그렇습니다.
    앞으로의 강좌에서, 나는 이를 위해 단원 테스트와 계약 테스트를 작성하는 방법을 소개할 것이다.
    평소와 같이github의 here 에서 원본 코드를 찾을 수 있습니다
    감사합니다!
    평화롭다
    주의: 이 블로그가 당신에게 도움이 되고 감사의 마음을 전하고 싶다면 언제든지 방문하세요.

    이것은 내가 더욱 가치 있는 내용을 공헌하는 데 도움을 줄 것이다.

    좋은 웹페이지 즐겨찾기