배포 시 META-INF에 context.xml 파일이 존재하면 문제를 발생시킬 수 있다. 

pom.xml

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <warName>${build.war.name}</warName>
                    
                    <!-- web.xml 파일이 없어도 에러 발생 무시 -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    
                    <!-- target 안에 있는 source-file/META-INF/context.xml 제외  -->
                    <warSourceExcludes>META-INF/context.xml</warSourceExcludes>
                    
                    <!-- target 안에 있는 war-file/META-INF/context.xml 제외  -->
                    <packagingExcludes>META-INF/context.xml</packagingExcludes>
                
                </configuration>
            </plugin>

 

1. REST(Representational State Transfer)란?

REST는 WWW(월드 와이드 웹)와 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식입니다.

REST는 올바른 HTTP 사용을 유도하고 있기 때문에 HTTP 장점을 최대한 살린 서비스를 설계할 수 있습니다.
REST의 기본 원칙을 성실하게 지킨 서비스를 "RESTful 하다"라고 표현합니다.

 

2. REST 필수 규칙

* URI는 정보의 자원을 표현해야한다.
* 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)으로 표현한다.
* 특정 행위의 표현은 JSON, XML 등을 이용한다. 
POST http://localhost/bamdule/members
{
   "name" : "kim",
   "email" : "xxxx@gmail.com"
}

// member 저장

 

3. HTTP Method 설명

Method 역할
POST Resource 생성
GET Resource 조회
PUT Resource 수정
DELETE Resource 삭제

 

4. Collection과 Document

Document
1개의 개체를 나타내는 것으로 객체 인스턴스, DB의 Record와 유사한 개념을 가집니다. 
일반적으로 리소스의 집합 중 하나를 의미하며 Collection 뒤에 위치합니다.

Collection
Document들의 묶음입니다. 일반적으로 복수 형태의 단어를 사용합니다.

예제
http://localhost/members/{id}
members가 Collections이고 {id}가 Document를 의미합니다.

 

3. REST API 디자인 가이드

- URI는 정보의 자원을 표현해야합니다.
- 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)으로 표현합니다.
- 특정 행위의 표현은 JSON, XML 등을 이용합니다.
- 리소스 명은 동사보다 명사를 사용합니다.

1) 데이터 조회(GET)

GET http://localhost/bamdule/members
{
  "name" : "kim",
  "page" : 2,
  "rows" : 20 
}
members 중에서 이름이 kim인 member들를 조회한다. (2페이지에 20개씩 조회)

2) 데이터 삽입(POST)

POST http://localhost/bamdule/members
{
  "name" : "kim",
  "email" : "xxxx@gmail.com",
  "birth" : "910505"
}
member를 생성한다.

3) 데이터 수정(PUT)

PUT http://localhost/bamdule/members/5
{
  "name" : "lee"
  "email" : "xxxx@gmail.com",
  "birth" : "971205"
}
id가 5번인 member를 수정한다.

4) 데이터 삭제 (DELETE)

DELETE http://localhost/bamdule/members/5
id가 5번인 member를 삭제한다.

 

4.URL Rules

  • URI 마지막에 "/"를 포함하지 않는다.

  • "_" 대신 "-" 를 사용한다.

  • 소문자를 사용한다.

  • 행위(method)는 URI에 포함하지 않는다.

  • 컨드롤 자원을 의미하는 URI은 예외적으로 동사를 허용한다. (ex : http://localhost/members/duplicate )
  • http accept는 aplication/json으로 기본으로 설정해라
  • "/"는 계층관계를 나타내는데 사용해라

  • URI에 자원의 행위를 명시하지 말아라 (ex : http://localhost/members/insert (x)  )

  • 리소스 간 관계를 표현할 때 다음과 같이 한다. 
GET http://localhost/members/{memberId}/boards

 

5. HTTP 응답 코드

1) 2xx 성공

  • 200: 클라이언트의 요청을 정상적으로 수행
  • 201: 클라이언트에게 생성 작업을 요청 받았고, 생성 작업을 성공
  • 204: 요청은 성공 했지만 응답할 콘텐츠가 없음

2) 3xx 리다이렉션

  • 301: 클라이언트가 요청한 리소스에 대한 URI가 영구적으로 변경되었을 때 사용함.
  • 302: 301과 같으나 임시적으로 주소가 바뀌었을 경우 사용함.
  • 304: 이전에 방문했을 때의 요청 결과와 다르지 않을 경우 사용함. 캐시된 페이지를 그대로 사용.
  • 307: 임시 페이지로 리다이렉트.

3) 4xx 클라이언트 오류

  • 400: 클라이언트가 올바르지 못한 요청을 보냄.
  • 401: 로그인을 하지 않아 페이지를 열 권한이 없음.
  • 403: 금지된 페이지, 로그인을 하든 안하든 접근할 수 없음. (관리자 페이지)
  • 404: 찾을 수 없는 페이지, 주소를 잘 못 입력했을 때 사용함.
    403 대신에 사용할 수도 있음.(해커들의 공격을 방지하고자 페이지가 없는 것처럼 위장함)
  • 408: 요청 시간이 초과됨.
  • 409: 서버가 요청을 처리하는 과정에서 충돌이 발생한 경우. (회원가입 중 중복된 아이디인 경우)
  • 410: 영구적으로 사용할 수 없는 페이지.

4) 5xx 서버 오류

  • 501: 해당 요청을 처리하는 기능이 만들어지지 않음.
  • 502: 서버로 가능 요청이 중간에서 유실된 경우.
  • 503: 서버가 터졌거나 유지 보수 중
    (유지 보수 중일때는 유지 보수중이라는 것을 알려주는 페이지로 전송해주는 것이 좋음)
  • 504: 서버 게이트웨이에 문제가 생겨 시간 초과가 된 경우.
  • 505: HTTP 버전이 달라 요청이 처리할 수 없음.

참조

spoqa.github.io/2012/02/27/rest-introduction.html
ko.wikipedia.org/wiki/REST
sanghaklee.tistory.com/57
velog.io/@stampid/REST-API%EC%99%80-RESTful-API

'IT > WEB' 카테고리의 다른 글

[CSS] CSS 변수 사용하기  (0) 2021.01.24
[WEB] CSRF란 ?  (0) 2020.07.30
[WEB] HTTP의 특징과 HTTP Message  (0) 2020.07.30

1. JWT(Json Web Token)란?

JWT는 개체와 개체 간에 정보 전달권한 인가(Authorization)를 위해 사용되는 토큰입니다.
URL-safety하기 때문에 Header 또는 URL을 통해 전달합니다.


2. JWT 구조

JWT는 Header, Payload, Signature로 이루어져있습니다.
각 부분은 Json형태로 저장되어 있으며, 각각 Base64로 인코딩 되어 있고, "." 을 구분자로 각각 부분을 구분합니다.

Header : 토큰에 대한 기본정보
Payload : 전달할 정보
signature : 검증된 토큰 정보 

 

1) HEADER(헤더)

토큰에 대한 기본 정보가 저장됩니다.

alg : Signature를 어떤 알고리즘으로 암호화 했는지 명시한다. (ex : SHA256, RSA)
typ : 토큰의 타입을 지정한다. (ex : jwt)


2) PAYLOAD(페이로드)

전달하려고 하는 정보가 저장되어있습니다. PAYLOAD는 크게 3가지로 구분됩니다. 

등록된 클레임(Registered Claim)
이름이 이미 정해진 클레임입니다. 등록된 클레임은 모두 선택적으로 사용할 수 있습니다.

iss(issuer) : 토큰 발급자
sub(subject) : 토큰 제목
aud(audience) : 토큰 대상자
exp(expiration) : 토큰 만료 시간, NumericDate 형식으로 저장된다. (ex : 1480849147370)
nbf(not before) : 토큰 활성 날짜, 이 날이 지나기전에 토큰이 활성화되지 않는다.
iat(isuued at) : 토큰 발급 시간, 토큰 발급 이후의 경과시간을 알 수 있다.
jti : JWT의 고유 식별자, 중복적인 처리를 방지하기 위해서 사용한다. 

공개 클레임(Public Claim)
사용자 정의 클레임으로, 공개용 정보를 위해 사용됩니다.

비공개 클레임(Private Claim)
서버와 클라이언트 간 협의하에 사용되는 클레임입니다. 

3) Signature(서명)

토큰의 유효성을 검증할 때 사용하는 서명입니다. 서명은 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고 "."를 구분자로 붙여줍니다. 그리고 비밀키를 이용해 헤더에서 정의한 알고리즘으로 암호화한 후, 다시 BASE64로 인코딩합니다.

//sha256으로 암호화 할 경우

header = base64_encode(header_json)
payload = base64_encode(payload_json);
signature = base64_encode(HMAC_SHA256(header + "." + payload, secret))
jwt = header + "." + payload + "." + signature


3. JWT의 용도 

회원 인증 
회원이 로그인을 하면 서버는 회원정보가 담긴 토큰을 발급해 줍니다. 그리고 회원이 서버에 데이터를 요청 할 때 마다 발급 받은 토큰 정보를 함께 전달하여, 인증받은 회원이라는 것을 증명합니다. 

정보 전달 
JWT는 Signature 정보를 이용해서 데이터 조작을 방지할 수 있으며, 안전하게 정보를 전달할 수 있습니다.


4. JWT의 장단점

장점

1) Stateless이며 확장성이 있다. 
서버와 클라이언트 간에 상태 정보를 저장하지 않으며 토큰을 가지고 있고 유효하다면 서버로 부터 데이터를 요청할 수 있습니다. 즉 개체간에 연결을 유지하지 않아도 됩니다.

서버를 여러대 사용하거나, 클라이언트 단말의 종류(PC, 모바일 등..)가 다양할 경우에도 토큰만 유효하다면 어떤 단말이든지간에 서버로 부터 데이터를 받을 수 있습니다. 
즉 JWT 인증 시스템을 만들어 두면 플랫폼에 상관없이 회원 인증 시스템 및 정보 전달이 가능합니다. 

2) 사용자 인증에 필요한 인증 저장소가 필요없다.
인증 정보가 토큰 자체에 포함되어있기 때문에 별도의 인증 저장소가 필요없습니다.

단점

1) 한번 발급된 토큰은 수정 및 삭제할 수 없다.
JWT는 stateless하기 때문에 토큰에 대한 정보를 관리하지 않습니다. 그래서 한번 만들어진 토큰은 삭제, 수정할 수 없습니다. 만약 토큰이 유출된다면 토큰이 만료될 때 까지 토큰을 가로챈 사용자가 서비스를 이용할 수 있습니다.

2) Payload 인코딩
Payload 값이 암호화된 값이 아닌 Base64로 인코딩 된 값이라 누구나 확인할 수 있습니다.
그래서 중요한 정보를 Payload에 저장해서는 안됩니다.

 

참조

https://mangkyu.tistory.com/56

https://jwt.io/

'IT > 기타' 카테고리의 다른 글

[Javascript] Jqgrid Custom  (0) 2020.09.14
[DEV] 컴파일과 빌드란  (0) 2020.09.10
[보안] 공개키 암호화 방식  (0) 2020.07.20
XSS란?  (0) 2020.07.16
OAuth2 란?  (1) 2020.02.29

목표
mariadb & mybatis 연동

 

1. pom.xml

...

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
          
    </dependencies>

...

 

2. application.yml

spring :    
    devtools :
        livereload :
            enalbed : true
    thymeleaf:
        cache : false       
    datasource:
        hikari :
            maximum-pool-size : 4
        url : jdbc:mariadb://localhost:3306/bamdule
        username : root
        password : 12345678
        
        
mybatis :
    type-aliases-package : com.bamdule.model
    mapper-locations : mapper/xml/*.xml

 

3. mapper-member.xml

mybatis를 이용해서 테이블 쿼리를 정의하는 XML 파일 생성 

1) src/main/resources/mapper/xml 디렉토리 생성
2) xml 디렉토리에 mapper-member.xml 파일 생성
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.bamdule.db.mapper.MemberMapper">
    
    <select id="selectMember" resultType="map" >
        SELECT *
        FROM member
    </select>
</mapper>

Member 테이블 명세

CREATE TABLE `member` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`email` VARCHAR(100) NOT NULL COLLATE 'utf8_general_ci',
	`PASSWORD` VARCHAR(100) NOT NULL COLLATE 'utf8_general_ci',
	`NAME` VARCHAR(100) NOT NULL COLLATE 'utf8_general_ci',
	PRIMARY KEY (`id`) USING BTREE,
	UNIQUE INDEX `email` (`email`) USING BTREE
);

 

4. Member Mapper 생성  

1) com.bamdule.db.mapper package 생성
2) mapper 안에 MemberMapper Interface 생성
3) Mapper 컴퍼넌트 선언 후 selectMember 메소드 정의
package com.bamdule.db.mapper;

import java.util.Map;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MemberMapper {

    public Map<String, Object> selectMember();
}

 

5. Member Service 생성

1) com.bamdule.db.service.impl package 생성
2 MemberService와 MemberServiceImpl 클래스 생성
package com.bamdule.db.service;

import java.util.Map;

public interface MemberService {

    Map<String, Object> selectMember();

}
package com.bamdule.db.service.impl;

import com.bamdule.db.mapper.MemberMapper;
import com.bamdule.db.service.MemberService;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memeberMapper;

    @Override
    public Map<String, Object> selectMember() {
        return memeberMapper.selectMember();
    }

}

 

6. HomeController에서 selectMember 결과 콘솔 출력

package com.bamdule.controller;

import com.bamdule.db.service.MemberService;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/")
public class HomeController {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MemberService memberService;

    @GetMapping("/")
    public String homeView() {
        Map<String, Object> member = memberService.selectMember();
        logger.info("[MYTEST] {}", member);
        return "page/home";
    }

}

 

logback 설정을 하지 않은 분은 아래 링크를 참고하여 설정해주세요.

2020/01/03 - [IT/Spring] - [Spring Boot] Logback 설정 방법

 

7. 결과

[MYTEST] {PASSWORD=123, id=1, email=test, NAME=kim}

1. Replace 함수란?

특정 문자열을 원하는 문자열로 변환하는 함수이다.

replace(컬럼명, '기존문자열', '변경문자열')

 

2. 사용 방법 

1) select

replace함수 실행 결과 추출하기

SELECT replace(url, 'http://' ,'https://') FROM file_info;

2) update 

'http://' 문자열이 포함된 컬럼을 'https://'로 변경

UPDATE file_info SET url = replace(url, 'http://' ,'https://');

Jqgrid 4.7.1

function CustomGrid(option) {

    var {gridId, form, url, data} = option;
    var postData;

    if (nonEmpty(form) && nonEmpty(data)) {
        postData = $.extend({}, serializeObject(form), data);
    } else if (isEmpty(form)) {
        postData = data;
    } else {
        postData = serializeObject(form);
    }

    console.log(postData);

    var defaultOption = {
        datatype: 'json',
        mtype: 'POST',
        postData: postData,
        loadError: function (xhr, status, error) {
        },
        loadonce: false,
        rownumbers: true,
        autowidth: true,
        page: 1,
        multiselect: true,
        rowNum: 20,
        rowList: [10, 20, 50, 100],
        pager: $(`#${gridId}Pager`),
        viewrecords: true,
        sortable: true,
        height: 'auto',
        autoencode: true,
        shrinkToFit: true,
        rownumWidth: 50,
        gridview: true
    };

    var gridOption = $.extend({}, defaultOption, option);
    var grid = $(`#${gridId}`).jqGrid(gridOption);

    function reload() {
        jQuery(grid).jqGrid().setGridParam(
                {
                    datatype: 'json',
                    postData: isEmpty(form) ? {} : serializeObject(form),
                    url: url,
                    page: this.getPageNo()
                }
        ).trigger("reloadGrid");
    }


    function serializeObject(form) {
        var unindexed_array = form.serializeArray();
        var indexed_array = {};

        $.map(unindexed_array, function (n, i) {
            indexed_array[n['name']] = n['value'];
        });

        return indexed_array;
    }

    function isEmpty(str) {
        return str === "" || str === undefined || str === null;
    }
    function nonEmpty(str) {
        return !isEmpty(str);
    }

    function isEmptyObject(obj) {
        return Object.keys(obj).length === 0 && obj.constructor === Object;
    }

    this.selectRowDelete = function () {
        var selectId = this.getSelectId();
        grid.jqGrid('delRowData', selectId);

        return selectId;
    };

    this.selectRowsDelete = function () {
        var selectIds = this.getSelectIds();
        var ids = [];

        for (var index = selectIds.length - 1; index > -1; index--) {
            ids.push(selectIds[index]);
            grid.jqGrid('delRowData', selectIds[index]);
        }

        return ids;
    };

    this.getPageNo = function () {
        return grid[0].p.page;
    };

    this.getRowIds = function () {
        return grid.jqGrid('getDataIDs');
    };

    this.getRowById = function (id) {
        return grid.jqGrid('getRowData', id);
    };

    this.getSelectRow = function () {
        return this.getRowById(this.getSelectId());
    };
    this.getSelectRows = function () {
        var selectIds = this.getSelectIds();
        var rows = [];
        for (var id of selectIds) {
            rows.push(this.getRowById(id));
        }
        return rows;
    };

    this.getSelectId = function () {
        return grid.jqGrid('getGridParam', 'selrow');
    };
    this.getSelectIds = function () {
        return grid.jqGrid('getGridParam', 'selarrrow');
    };

    this.getCell = function (id, colName) {
        return grid.jqGrid('getCell', id, colName);
    };

    this.addRow = function (id, rowData, loc) {
        if (isEmptyObject(rowData)) {
            return false;
        } else {
            if (isEmpty(loc)) {
                loc = 'last';
            }
            grid.jqGrid("addRowData", id, rowData, loc); // 마지막 행에 Row 추가
            return true;
        }
    };

    this.addUniqueRow = function (id, rowData, loc) {
        var row = this.getRowById(id);

        if (isEmptyObject(row)) {
            this.addRow(id, rowData, loc);
            return true;
        } else {
            return false;
        }
    };

    this.dragAndDrop = function () {
        grid.sortableRows();
        grid.jqGrid('gridDnD');
    };

    this.grid = grid;
    this.reload = reload;

    this.changeRowColor = function (id, color) {
        grid.jqGrid("setRowData", id, false, {background: color});
    };

}

'IT > 기타' 카테고리의 다른 글

[JWT] Json Web Token이란?  (0) 2020.10.02
[DEV] 컴파일과 빌드란  (0) 2020.09.10
[보안] 공개키 암호화 방식  (0) 2020.07.20
XSS란?  (0) 2020.07.16
OAuth2 란?  (1) 2020.02.29

개발하면서 컴파일과 빌드를 수도 없이 하지만 그에 대한 정확한 의미를 알지 못했다.

인터넷 검색을 통해 이해한 사실을 정리해보고자 한다.

1. 컴파일(Compile)

개발자가 작성한 소스코드를 컴파일러(Compiler)를 통해 바이너리 코드로 변환하는 과정을 말한다.
즉, 소스코드를 컴퓨터가 이해할 수 있는 기계어로 변환하는 작업을 말한다.

자바의 경우 member.java를 자바 컴파일러를 통해 member.class로 변환하는 과정을 의미한다.  
(member.class는 JVM(자바가상머신)에서 실행가능한 바이트코드이다.)

 

2. 링크(Link)

A라는 소스코드에서 B라는 소스코드를 호출하는 경우 A와 B를 연결해주는 작업

정적 링크
컴파일해서 나온 바이너리 코드와 정적 라이브러리를 직접 링크하여 하나의 실행파일을 만드는 과정을 의미한다.
그래서 정적 링크 시, 라이브러리 파일을 찾지 못하면 링크에러가 발생한다.
정적 링크의 단점은 링크 시 연결된 모든 소스를 로드하기 때문에 실행파일이 커지고 메모리 공간 효율이 떨어지게 된다.

동적 링크
실행파일과 라이브러리 파일이 독립적이다.
프로그램 실행 도중 필요한 라이브러리가 생기면 동적으로 연결하는 작업을 의미한다. 자바의 경우 JVM이 프로그램 실행 도중 필요한 클래스를 찾아서 클래스 패스에 로드해주는데 이것이 동적링크의 예이다.

3. 빌드(Build)

소스코드 파일을 실행가능한 소프트웨어 산출물로 만드는 일련의 과정을 말한다. 
빌드에서는 컴파일, 테스트, 배포 등 과정이 포함될 수 있고, 빌드 과정을 도와주는 도구를 빌드 툴이라 한다.

자바를 예로 들자면 빌드 시 컴파일, 테스팅, 패키징등 작업이 일어난 후 target폴더 안에 생성되는 .jar, .war 것을 의미한다.

빌드 툴로는 Ant, Maven, Gradle 등이 있다.

출처 : freezboi.tistory.com/39

 

컴파일과 빌드 차이점

평소 이클립스와 같은 IDE를 사용하기 때문에 컴파일과 빌드의 개념에 대해 잘 알지 못했다. 단지 소스코드를 작성하고 이클립스에서 run을 실행하면 알아서 모든 과정이 자동으로 실행되기 때문

freezboi.tistory.com

 

'IT > 기타' 카테고리의 다른 글

[JWT] Json Web Token이란?  (0) 2020.10.02
[Javascript] Jqgrid Custom  (0) 2020.09.14
[보안] 공개키 암호화 방식  (0) 2020.07.20
XSS란?  (0) 2020.07.16
OAuth2 란?  (1) 2020.02.29

1. aws cli 다운로드

1) 파이썬 다운로드
# yum install python

2) get-pip.py 다운로드
# curl -O https://bootstrap.pypa.io/get-pip.py

3) get-pip.py 실행
# python get-pip.
py

4) pip 버전 확인
# pip --version

5) pip를 이용해서 awscli 설치
# pip install awscli

6) aws 버전 확인
# aws --version

 

2. aws configure 등록

# aws configure list

AccessKey, SecretKey IAM(Identity and Access Management)에서 사용자를 등록하면 발급 받을 수 있습니다.

# aws configure
access_key : ############
secret_key : ############
region : (ex : ap-northeast-2)
format : (ex : json)

 

3. S3 모든 파일 다운로드 및 업로드

3. aws s3 명령어

1) help

# aws s3 help

다양한 aws cli s3 명령어 설명을 확인할 수 있습니다.

2) cp(복사), mv(이동), rm(삭제)

로컬에서 S3 버킷으로 데이터를 업로드하거나, 다운로드 할 수 있습니다.
사용방법은 각 명령어마다 유사하기 때문에 cp를 기준으로 명령어를 사용하겠습니다.

1. S3 버킷 > 로컬
1) 일부 파일
# aws s3 cp s3://bucketName/Path/test.txt ./

2)디렉토리 전체
# aws s3 cp s3://bucketName/Path ./ --recursive

2. 로컬 > S3 버킷
1) 일부 파일

# aws s3 cp test.txt s3://bucketName/Path 
2) 디렉토리 전체
# aws s3 cp ./ s3://bucketName/Path --recursive

3) ls(목록), mb(버킷 생성), rb(버킷 삭제), sync(동기화)

1). 버킷 목록보기
# aws s3 ls s3://bucketName
2). 버킷 생성

# aws s3 mb s3://bucketName
버킷 삭제

# aws s3 rb s3://bucketName

4)버킷 동기화
aws s3 sync /local s3://bucketName
aws s3 syncs3://bucketName/local
aws s3 syncs3://bucketName1s3://bucketName2

+ Recent posts