如何实现Laravel认证用户访问纯PHP页面并拦截未授权用户
Laravel与原生PHP跨项目认证拦截实现
核心逻辑是打通两个项目的会话读取链路,让原生PHP可以合法校验Laravel颁发的登录凭证,再在页面入口加拦截规则即可。
前置配置要求
两个项目必须满足以下基础条件才能共享认证状态:
- 部署在同一一级域名下(例如Laravel域名为
laravel.demo.com,原生PHP域名为raw.demo.com),否则跨域cookie无法生效,需要改用签名token跳转方案 - 会话存储统一:如果用文件驱动存session,将Laravel的
config/session.php中files路径修改为两个项目都有读写权限的共享目录;如果用Redis、数据库驱动,确保两个项目能连接同一个会话存储实例 - 配置对齐:
- 修改Laravel端
config/session.php的domain值为.demo.com(前面带点,覆盖所有子域名),记住cookie项的名称(默认是laravel_session) - 复制Laravel项目
.env文件中APP_KEY的值,去掉开头的base64:前缀后做base64解码,后续原生PHP解密会话需要用到这个密钥
- 修改Laravel端
原生PHP侧认证拦截代码
在原生PHP项目根目录新建公共校验文件auth_intercept.php,所有需要登录才能访问的页面都在开头引入这个文件:
<?php // 对齐Laravel会话cookie配置 session_name('laravel_session'); // 和Laravel session配置里的cookie名保持一致 session_set_cookie_params([ 'domain' => '.demo.com', // 和Laravel配置的会话域名一致 'path' => '/', 'secure' => false, // 如果站点是HTTPS就改成true,和Laravel配置对齐 'httponly' => true, ]); session_start(); $isAuthenticated = false; $currentUserId = null; $laravelAppKey = base64_decode('这里填你刚才处理好的Laravel APP_KEY'); // 读取会话内容,这里以文件驱动为例,用Redis/数据库的话替换对应读取逻辑即可 if (isset($_COOKIE['laravel_session'])) { $sessionId = $_COOKIE['laravel_session']; // 替换成你配置的共享session存储路径 $sessionPath = '/path/to/shared/session/dir/' . $sessionId; if (file_exists($sessionPath)) { $rawSession = file_get_contents($sessionPath); // 解密Laravel加密的会话数据 $iv = substr($rawSession, 0, 16); $decryptedSession = openssl_decrypt( $rawSession, 'AES-256-CBC', $laravelAppKey, 0, $iv ); if ($decryptedSession) { $sessionData = unserialize(substr($decryptedSession, 16)); // 校验Laravel登录标记,默认登录后会话会存login_web_前缀的用户ID foreach ($sessionData as $key => $val) { if (substr($key, 0, 10) === 'login_web_') { $isAuthenticated = true; $currentUserId = $val; break; } } } } } // 未登录直接拦截跳转 if (!$isAuthenticated) { header('Location: http://laravel.demo.com/login'); exit; } // 登录状态下可以把用户ID挂到全局,页面业务逻辑直接用 $GLOBALS['auth_user_id'] = $currentUserId; ?>
注:PHP8及以上版本可以把substr($key, 0, 10) === 'login_web_'替换成str_starts_with($key, 'login_web_'),写法更简洁
受限页面接入拦截
所有需要控制访问权限的原生PHP页面,在文件最顶部引入校验文件即可:
<?php require __DIR__ . '/auth_intercept.php'; // 以下是页面自身的业务代码 ?>
补充说明
- 如果不想手写解密逻辑,可以在原生PHP项目中通过Composer安装Laravel的
illuminate/encryption、illuminate/session组件,直接调用Laravel原生方法解析会话,兼容性更好 - 如果两个项目无法部署在同一一级域名下,放弃cookie共享方案:改成Laravel登录后跳转原生项目时携带带过期时间、带签名的临时token,原生项目校验token合法后生成自身会话即可
- 可以额外加一层请求来源校验、会话过期时间二次校验,提升安全性
内容的提问来源于stack exchange,提问作者Mohamed Eid
相关产品推荐
相关产品推荐

