by Devin Yang

建立於: 1年前 ( 更新: 1年前 )

為何我把網站的搞前後台分離,我的想法很簡單,就是靠一套後台管控所有前台的網站資料。
假設前台的網站為單純的行銷網站,那不外乎主題內容,就是上上文章那種,沒有什麼特別複雜的邏輯。
所以後台的資料庫設記好連不同的前台就好了,那還剩最後一個問題,我的後台HTML編輯器如何貼圖直接貼文到前台呢?
Laravel的Storage SFT Driver就是很好的解藥。

如何做
後台部份:
一、在後台安裝sftp套件

composer require league/flysystem-sftp-v3 "^3.0"

二、在後台建立OpenSSH鑰匙對

dlaravel@05620df95284:~/html/storage/app$ ssh-keygen -t ed25519 -C "storage demo"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/dlaravel/.ssh/id_ed25519): storage 
storage already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in storage.
Your public key has been saved in storage.pub.
The key fingerprint is:
SHA256:LKl4GvrV+0Q9urecEtYfJPf7Cgha441TbUS4+r/1R/4 storage demo
The key's randomart image is:
+--[ED25519 256]--+
|           ..    |
|          ..     |
|           ..    |
|       o .ooo    |
|      o So++o.   |
|   . o *+B.+. . .|
|  o + o.*oo....+ |
| . =   o.+o..o..o|
|..o   ..oo+oo..oE|
+----[SHA256]-----+
dlaravel@05620df95284:~/html/storage/app

三、設定後台的config/filesystems.php的disks array中加入

'sftp' => [
    'driver' => 'sftp',
    'host' => env('SFTP_HOST'),
    // Settings for basic uthentication...
    'username' => env('SFTP_USERNAME'),
    'privateKey' => env('SFTP_PRIVATE_KEY'),
    'passphrase' => env('SFTP_PASSPHRASE'),
    'port' => env('SFTP_PORT', 2258),
    'root' => env('SFTP_ROOT', '/var/www/html/storage/app/public'),
    'url' => env("SFTP_URL").'/storage'
],

四、我們可以cat剛產出的公鑰,將他拷貝起來。

dlaravel@05620df95284:~/html/storage/app$ cat storage.pub 
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd1tsK2CqnRhVN5zbbJvi+Wpua+GWmbcazshpoRS0r7 storage demo
dlaravel@05620df95284:~/html/storage/app$ 

五、將公鑰加到前台,因為我前台採用deviny/phpenv的容器環境,所以放入host端的authorized_keys即可。

六、回到後台主機,調整.env如下:
PORT的部份我寫死在上方第三步config/filesystem.php中,因為他只吃數字。

FILESYSTEM_DISK=sftp
SFTP_URL=https://www.ccc.tc
SFTP_USERNAME=dlaravel
SFTP_HOST=192.168.99.2
SFTP_PASSPHRASE=demo
SFTP_PRIVATE_KEY=/home/dlaravel/html/storage/app/storage

七、開始,直接用tinker開測,方便簡單又好用。
由於預設的檔案系統使用是sftp不是local了,所以我的Storage指令不用再加Storage::diks("sftp")
打files列出目錄內的圖檔,輕鬆搞定。



八、我的後台使用的CKEditor 5的simpleUpload,在Javascript的部份我用了,jwt驗證,需通過才可上傳檔案。

simpleUpload: {
    uploadUrl: '/圖檔上傳路徑',
    headers: {
        'X-CSRF-TOKEN': '{{csrf_token()}}',
        Authorization: 'Bearer {{$jwt}}'
    }
},

九、Controller的部份內容如下:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\ValidationException;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class ImageUploaderController extends Controller
{
    public function store(Request $request)
    {
        $key = env("APP_KEY");
        //Log::info($request->headers);
        $jwt_token = $request->bearerToken();
        //JWT驗證不過就不給上傳
        try {
            $decoded = JWT::decode($jwt_token, new Key($key, 'HS256'));
        } catch (\Exception $e) {
            abort(403);
        }
        //只允許上傳jpg,bmp,png,gif
        try {
            $request->validate(['upload' => 'mimes:jpg,bmp,png,gif']);
        } catch (ValidationException $e) {
            Log::info($e->getMessage());
            return ["error" => ["message" => $e->getMessage()]];
        }
        //依Storage的driver設定調整上傳檔案存方位置
        if (env("FILESYSTEM_DISK") == "local") {
            //本地端預設的根目錄在storage/app
            $path = Storage::putFile('public/images', $request->file('upload'));
        }else{
            //sftp drvier中指定了root在storage/app/public,所以這裡直接put file到images資料夾
            $path = Storage::putFile('images', $request->file('upload'));
        }
        $url = Storage::url($path);
        return ["url" => $url];
    }
}

直接來瞧瞧我的畫面,本篇網站的圖檔,我就是這麼拷貼上的:😆
這個後台的網站的域名並不是www.ccc.tc哦,是另一個網站,完全透過了Laravel的Storage搞定。


 Laravel的官方文件,可以由下方網址開啟:
https://laravel.com/docs/9.x/filesystem#sftp-driver-configuration

 

Tags: laravel-storage sftp

Devin Yang

文章內容無法一一說明,如果您有什麼不了解處,歡迎提問哦:)

No Comment

Post your comment

需要登入才可留言!