laravel

自制的laravel第三方包无法读写session的问题记录

2022年4月8日 laravel

自己开发的laravel第三方composer包,由于需要使用到session,包配置成自动发现,在ServiceProvider的boot中添加了自动加载路由 loadRoutesFrom 结果死活不能正常使用。

最后各种搜索发现,原因是 “StartSession” 仅被添加到web中间件中,必须给包路由加了 [‘middleware’=>’web’]才可以正常使用session

laravel-echo-server 记一次认证失败原因403

2022年3月24日 laravel

自定义private-channel时,避免使用private-开头的频道名,系统默认的模型认证会在频道名上自动加上‘private-’前缀,自定义频道名时,避开这规则,同时在config/channels.php里对自定义的私有频道进行登录权限验证,如:

Broadcast::channel('custom-private-channel-{id}', function ($user, $id) {
    if( is_numeric($id) ){
        return (int) $user->id === (int) $id;
    }else{
        return session()->getId() === $id;
    }
});

在laravel-echo-server.json设置devMode=true查看日志,确认所有验证能正常通过后,私有频道即可监听到。

laravel 处理 http_build_query() 参数中的 PHP_QUERY_RFC3986(URL编码协议)

2022年1月10日 laravel, PHP

原生 http_build_query() 方法定义:

function http_build_query (object|array $data, string $numeric_prefix = "", ?string $arg_separator = "&", int $encoding_type = PHP_QUERY_RFC1738)

指定使用 PHP_QUERY_RFC3986:

$query = http_build_query($query_data, null, null, PHP_QUERY_RFC3986);

laravel:

GuzzleHttp\Psr7\Query::build() 默认使用 PHP_QUERY_RFC3986

方法定义:

public static function build(array $params, $encoding = PHP_QUERY_RFC3986)

laravel6.x 使用 config:cache 导致 env() 函数不能直接读取.env 文件

2022年1月8日 laravel

线上环境一但使用 php artisan config:cache 就会各种异常,最终检查原因是使用 config:cache 后env() 是无法读取 .env文件配置的。

 

将 config 文件之外的所有 env() 方法使用 config() 代替

如:

在 config/app.php 中添加:'force_https' => env('FORCE_HTTPS', false),

调用时使用 config('app.force_https')

 

PS: 通过composer引用的包不受此影响

关于laravel6 的https踩坑记录

2022年1月6日 laravel

开发环境是http的,线上环境https,导致线上资源加载http而无法加载。

大多网友遇到问题是通过给asset()加第二个参数,或使用secure_asset()代替

两个方法都要修改所有引用的blade,还有一些第三方blade重写更加麻烦,如horizon的单页面

废话少说,解决方案:

 

1、.env 添加ASSET_URL=xxx 与APP_URL一致,用于给asset()添加固定的https前缀

2、.env 添加 FORCE_HTTPS=true,本地环境false

3、config/app.php 添加'force_https' => env('FORCE_HTTPS', false)

4、AppServiceProvider boot() 里添加如下代码,用于解决url()生成https链接

        if( config('app.force_https') ){
            \Url::forceScheme('https');
        }

5、AppServiceProvider register() 里添加如下代码,用于解决pjax加载https

        if( config('app.force_https') ) {
            $this->app['request']->server->set('HTTPS', true);
        }

6、测试,OK

Key path “file:///tmp/oauth-private.key” does not exist or is not readable 原因

2021年7月1日 laravel

[LogicException]                                                                   
  Key path "file:///tmp/oauth-private.key" does not exist or is not readable  

laravel-s服务器,通过laravel/passport鉴权时总是报上面错,后面发现是php bin/laravels start的启动用户权限问题,启动laravels的用户没有passport的密钥读取权限

supervisor 启动 laravel-echo-server 关于设置 startsecs

2021年6月23日 laravel

laravel-echo-server启动需要比较长时间,如果通过supervisor来监控laravel-echo-server的运行状态,极有可能在默认情况下超时导致重新启动,很容易就死循环了。

startsecs默认是10,如果进程启动有可能超过10秒,则设置大一点吧

;[program:example]
;command=/bin/echo; the program (relative uses PATH, can take args)
;priority=999                ; the relative start priority (default 999)
;autostart=true              ; start at supervisord start (default: true)
;autorestart=true            ; retstart at unexpected quit (default: true)
;startsecs=10                ; number of secs prog must stay running (def. 10)
;startretries=3              ; max # of serial start failures (default 3)
;exitcodes=0,2               ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT             ; signal used to kill process (default TERM)
;stopwaitsecs=10             ; max num secs to wait before SIGKILL (default 10)
;user=chrism                 ; setuid to this UNIX account to run the program
;log_stdout=true             ; if true, log program stdout (default true)
;log_stderr=true             ; if true, log program stderr (def false)
;logfile=/var/log/supervisor.log    ; child log path, use NONE for none; default AUTO
;logfile_maxbytes=1MB        ; max # logfile bytes b4 rotation (default 50MB)
;logfile_backups=10          ; # of logfile backups (default 10)
 

 

 

;command=/bin/echo;         supervisor启动时将要开启的进程。相对或绝对路径均可。若是相对路径则会从supervisord的$PATH变中查找。命令可带参数。
;priority=999                    指明进程启动和关闭的顺序。低优先级表明进程启动时较先启动关闭时较后关闭。高优先级表明进程启动时启动时较后启动关闭时较先关闭。
;autostart=true                  是否随supervisord启动而启动
;autorestart=true                进程意外退出后是否自动重启
;startsecs=10                    进程持续运行多久才认为是启动成功
;startretries=3                  重启失败的连续重试次数
;exitcodes=0,2                   若autostart设置为unexpected且监控的进程并非因为supervisord停止而退出,那么如果进程的退出码不在exitcode列表中supervisord将重启进程
;stopsignal=QUIT                 杀进程的信号
;stopwaitsecs=10                 向进程发出stopsignal后等待OS向supervisord返回SIGCHILD 的时间。若超时则supervisord将使用SIGKILL杀进程
 

composer self-update && composer clearcache

2021年6月23日 laravel

The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)
    Unzip with unzip command failed, falling back to ZipArchive class

好好的composer install死活不成功,提示上面信息,

又是

composer self-update

又是清除vendor重新安装的,没有效果


一顿google后,发现composer clearcache解决

laravel orderBy使用指定的自定义字符串顺序排序

2021年4月1日 laravel

laravel 使用 orderByRaw() 自定义排序

一般的排序 orderBy('column', 'asc')

现在要求按指定的字符串顺序排序:"FIELD(column,'". implode("','", array_reverse([‘aa’,’bb’,’cc’]))."') desc";

array_reverse 是将数组反序排序后再 desc ,最后得到的还是正序,目的是让不在指定范围内的往后排

假如记录中的column字段存在以下值:[‘cc’,’bb’,’dd’,’aa’,’ff’]

如果使用"FIELD(column,'". implode("','", [‘aa’,’bb’,’cc’])."')";

则得到的是'dd','ff'排在前面,然后才是'aa','bb','cc'

implode("','", [])是为了得到带‘号的拼接数组串,指定字符串列排序需要带上单引号,否则报错(数字则不用)

错误:FIELD(column, aa, bb, cc)

正确:FIELD(column, 'aa', 'bb', 'cc')

关于Laravel Passport一些踩坑记录

2020年9月3日 laravel

1、当Laravel使用多用户表api认证时,极容易因为默认guard为api导致认证失败(本人admin)

方案一:修改auth.defaults.guard 为 'admin'

      此方案导致我的web默认变成admin用户验证,还需要再做一堆处理…于是…

方案二:添加认证中间件

    public function handle($request, Closure $next, ...$guards)
    {
        if( strpos($request->route()->getName(), 'passport')!==false ) {
            config(['auth.defaults.guard' => 'admin']);
        }

        $this->authenticate($request, $guards);

        return $next($request);
    }

2、前后分离小应用

前后分离后端:添加中间件,自动生成laravel_token

    protected $middlewareGroups = [
        'web' => [
            ...
            \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
        ],

前后分离前端请求示例(注意不要直接复制下面代码,wp的引号自动替换成中文引号,我自己被自己的复制坑了半天时间)

            $.ajax({
                type: "GET",
                url: '{{ url('/api/user') }}',
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                dataType: 'json',
                success: function(res) {
                    console.log(res);
                }
            });
 
应用外请求token

            $.ajax({
                type: "POST",
                url: '{{ url('/oauth/personal-access-tokens') }}',
                data: {name: 'Token Name'},
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                dataType: 'json',
                success: function(res) {
                    console.log(res);
                }
            });

3、关于api_token认证

需要做接口登录换取token过程

建议一步到位,直接laravel/passport,用法更普遍,更强大,更标准

4、关于client_uuids

开启client_uuids = true记得要把id字段设置为varchar,原有id是自增的bigint

同时当

php artisan passport:install

生成client_id时可能会要求 "128-bit integer; Moontoast\Math\BigNumber is required. "

composer require moontoast/math

5、redirect_uri是oauth必须验证的一个参数,所以一定要保持参数与client设置的一致

6、Oauth支持的5类 grant_type 及说明

    authorization_code — 授权码模式(即先登录获取code,再获取token)

    password — 密码模式(将用户名,密码传过去,直接获取token)

    client_credentials — 客户端模式(无用户,用户向客户端注册,然后客户端以自己的名义向’服务端’获取资源)

    implicit — 简化模式(在redirect_uri 的Hash传递token; Auth客户端运行在浏览器中,如JS,Flash)

    refresh_token — 刷新access_token

7、遇到直接使用php artisan passport:install生成的Clinet无法通过authorization_code认证,
默认生成:Personal Access Client 或 Password Grant Client
通过新建Client解决

php artisan passport:client

8、

9、

10、

 

 

其它未完待续