Quay lại

Lưu trữ files trên s3 trong Laravel - Full Guide 2023 Chuyên mục PHP và Laravel    2023-07-01    943 Lượt xem    12 Lượt thích    comment-3 Created with Sketch Beta. 1 Bình luận

Lưu trữ files trên s3 trong Laravel - Full Guide 2023

Hello anh em chắc hẳn một trong số các anh em ở đây đã nghe nói đến s3 rồi đúng không, nó dùng để lưu trữ files của chúng ta trên cloud aws, nó không chỉ lưu được files mà nó còn lưu được ở dưới dạng web tĩnh html và lưu logs files nữa nói về công dụng thì các bạn đọc trên aws về nó nữa nhé...trong bài hôm này mình sẽ hướng dẫn các bạn làm thế nào để upload files lên trên s3 trong Laravel nhé ! Có thể xem video tại đây tầm giữa khoảng của video.

Bước 1: Tạo Bucket và User IAM trên S3

  1. Truy cập Bảng điều khiển dịch vụ web của Amazon và Đăng nhập
  2. Trên thanh công cụ tìm kiếm ở top menu hãy nhập service s3 và chọn s3
  3. Nhấp vào nút "Create Bucket" và bạn sẽ tìm thấy các biểu mẫu dưới đây. bạn có thể nhập tên Bucket của bạn ở đó

4. Tạo người dùng IAM. Nhấn vào đây để tạo IAM User.

5. Nhấp vào nút "Add User" như bên dưới hiển thị cho bạn.

6. Tiếp theo "Thêm tên người dùng" và chọn "Programmatic access" . sau đó bấm vào tiếp theo.

Lưu ý: Với user trong bài hướng dẫn này dùng chỉ để upload ảnh files thôi , không cần phải vào màn hình console để quản lý nên các bạn không cần chọn Programmatic access chỉ cần thêm tên người dùng là đủ rồi , còn trường hợp của bạn nào cần phải vào console thì hãy chọn "Provide user access to the AWS Management Console" sau đó thì chọn "I want to create an IAM user".

7. Bước tiếp theo tạo "User group"

Một popup hiện lên các bạn hãy nhập "group name" vào nhé , chỗ này mình sẽ giải thích qua một chút các bạn đừng vội tạo luôn nhé, khi các bạn search s3 policy thì một policy với tên là "AmazonS3FullAccess" xuất hiện như một cách bình thường dùng để test or để thực hành thì các bạn có thể chọn policy này cũng được ,Trên thực tế thì mình nghĩ là KHÔNG NÊN nha bởi khi chọn policy này thì tất cả các users trong group này cũng có thể truy cập vào "Bucket" của những dự án khác nữa và có tất cả các quyền thao tác luôn vì vậy không nên chọn mà thay vào đó hãy tạo ra một custom policy cho riêng user này và chỉ được cho phép sử dụng "Bucket" mà mình cho phép thôi nha chính vì thế các bạn hãy chọn "Create policy"

8. Bước tiếp theo tạo một custom "Policy" và thêm "Policy" cho user Group

Ở bước này các bạn hãy chọn "All S3 actions (s3:*)" và Trong phần "Resource" hãy chọn "Specific" và sau đó thì thêm  "Add Arn" cho "Bucket" và "Object"

1. Thêm "Add Arn" cho "Bucket" một popup hiện lên và các bạn nhập "Bucket name" mà bạn chỉ định nhé ví dụ như mình chỉ cho phép vào Bucket "bucket-laravel-dev-demo"

2. Thêm "Add Arn" cho "Object" một popup hiện lên và các bạn nhập "Bucket name" và "Object name" (Object name là những tài nguyên hay còn được hiểu là các folders hay files ở trong bucket của bạn nha) các bạn muốn cho truy cập vào hết các object thì chọn "Any" nha !

Bước tiếp theo các bạn nhập tên cho policy và nhấn create là xong rồi

Sau bước này các bạn quay lại màn or tab "User Group" và thêm policy mà chúng ta vừa tạo nhé ! 

Bước cuối cùng gán "User" mà chúng ta đang tạo vào "Group" và nhấn "Next and Create" là đã tạo xong một user IAM rồi !

9. Bây giờ các bạn hãy "Click" vào người dùng đã tạo và chọn "Security Credentials" để tạo "Access Key ID" và "Secret Access Key" mà chúng ta cần để setup .env của laravel nhé !

Sau đó thì cuộn xuống dưới và tìm tới mục "Access keys" chọn "Create Access key" , mục này các bạn có thể chọn option để chỉ ra rằng mục đích sử dụng các bạn có thể chọn "Local Code" or các option khác đều được ! Sau đó thì nhấn "Next" và create "Create Access key"

Ok vậy là xong hết cho phần trên aws rồi , bây giờ là dưới Laravel nữa thôi !

Bước 2: Cài Đặt Laravel

Trước hết, chúng ta cần cài đặt laravel mới nhất bằng cách sử dụng lệnh dưới đây vì chúng ta đang thực hiện lại từ đầu

composer create-project laravel/laravel example-practice

Bước 3: Cài đặt package Amazon S3 Composer

composer require --with-all-dependencies league/flysystem-aws-s3-v3 "^1.0"

Hoặc

composer require --with-all-dependencies league/flysystem-aws-s3-v3

Hoặc

composer require league/flysystem-aws-s3-v3

Bước 4: Configure AWS S3 Credentials

Bây giờ, bạn cần thêm thông tin đăng nhập aws vào tệp .env của mình như sau:

AWS_ACCESS_KEY_ID=AKIA2PNOEM23OAAPS4EQ
AWS_SECRET_ACCESS_KEY=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
AWS_DEFAULT_REGION=ap-southeast-1
AWS_BUCKET=my-laravel-bucket-t
AWS_USE_PATH_STYLE_ENDPOINT=false
  • AWS_ACCESS_KEY_ID : "Access key"
  • AWS_SECRET_ACCESS_KEY : "Secret access key"
  • AWS_DEFAULT_REGION : "Bucket Region" các bạn có thể lấy cái này trong bucket mà các bạn đã tạo (Quay lại Bước 1 và nhìn mục số 3 nhỏ "AWS Region = ap-southeast-1")
  • AWS_BUCKET: "bucket name"
  • AWS_USE_PATH_STYLE_ENDPOINT : "Đường dẫn path file"

Bước 5: Tạo Routes

Trong bước tiếp theo, chúng ta sẽ thêm hai route mới trong tệp web.php. Một route được tạo ra để tạo form để upload file và một route khác để xử lý logic để đẩy files lên s3, Vì vậy, Các bạn hãy tạo hai route được liệt kê dưới đây nha:

routes/web.php

<?php
  
use Illuminate\Support\Facades\Route;
  
use App\Http\Controllers\PostController;

Route::get('post', [ PostController::class, 'index' ])->name('post.index');
Route::post('store-image-post', [ PostController::class, 'storeImagePost' ])->name('image.post.store');

Bước 6: Tạo PostController

Trong bước thứ 5, chúng ta sẽ phải tạo PostController mới và ở đây chúng ta phải viết hai phương thức index()storeImagePost()

app/Http/Controllers/PostController.php

<?php
  
namespace App\Http\Controllers;
  
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\App;
use Carbon\Carbon;
  
class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('post.index');
    }
    
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function storeImagePost(Request $request)
    {
        $request->validate([
            'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);
    
        $file = $request->file('image');

        $path = $this->storeFile($file, 'images/');
  
        /* Lưu trữ tên $path trong CƠ SỞ DỮ LIỆU từ ĐÂY */
        //.....
        
        return back()
            ->with('success','Thành công upload file.')
            ->with('image', $path);
    }

     /**
     * Store Image and get filename
     *
     * @param UploadedFile $file
     * @param string $storagePath
     * @param string|null $fileName
     * @return string
     */
    public static function storeFile(UploadedFile $file, string $storagePath, ?string $fileName = null): string
    {
        $fileName = $fileName ?? $file->getClientOriginalName();

        $checkSumSHA256 = hash_file("sha256", $file);
        $metaData = [
            "ContentSHA256" => $checkSumSHA256
        ];

        Storage::putFileAs($storagePath, $file, $fileName, $metaData);

        if (!empty(self::getFileLink($fileName, $storagePath)))
            return $fileName;

        return '';
    }

    /**
     * get image url
     *
     * @param string $filename
     * @param string $filepath
     * @return string
     */
    public static function getFileLink(?string $filename, string $filepath): string
    {
        if (empty($filename)) return '';
        if (!App::environment('production') && env('FAKE_CURRENT_TIME')) {
            $testNow = Carbon::now()->toDateTimeString();
            Carbon::setTestNow();
            $expire = Carbon::now()->addMinute(5)->timestamp;
            Carbon::setTestNow($testNow);
        } else {
            $expire = Carbon::now()->addMinute(5)->timestamp;
        }
        if (config('filesystems.default') === 's3') {
            return Storage::temporaryUrl($filepath . $filename, $expire);
        }
        return Storage::url($filepath . $filename);
    }
}

Bước 7: Tạo Blade File

Ở bước cuối cùng, chúng ta cần tạo tệp index.blade.php và trong tệp này, chúng ta sẽ tạo form với input button để gửi file. 

resources/views/post/index.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Upload file lên s3 - s2sontech.com</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
    
<body>
<div class="container">
     
    <div class="panel panel-primary">
      <div class="panel-heading"><h2>Upload file lên s3</h2></div>
      <div class="panel-body">
     
        @if ($message = Session::get('success'))
        <div class="alert alert-success alert-block">
            <button type="button" class="close" data-dismiss="alert">×</button>
                <strong>{{ $message }}</strong>
        </div>
        <img src="{{ Session::get('image') }}">
        @endif
    
        @if (count($errors) > 0)
            <div class="alert alert-danger">
                <strong>Errors!</strong>
                <ul>
                    @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
        @endif
    
        <form action="{{ route('image.post.store') }}" method="POST" enctype="multipart/form-data">
            @csrf
            <div class="row">
    
                <div class="col-md-6">
                    <input type="file" name="image" class="form-control">
                </div>
     
                <div class="col-md-6">
                    <button type="submit" class="btn btn-success">Upload</button>
                </div>
     
            </div>
        </form>
    
      </div>
    </div>
</div>
</body>
  
</html>

Bây giờ bạn có thể chạy và kiểm tra nó.

php artisan serve

Bây giờ bạn có thể mở URL dưới đây trên trình duyệt của mình:

localhost:8000/post

Hình ảnh đã tải lên S3:

 
 

Bình luận (1)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Michael Gough   Son

Bài viết quá hay

Jese LeosSon

Đúng vậy !

Bài viết liên quan

Learning English Everyday