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

需要登入才可留言!