“免登录接口”通常指两种场景:

- 内部系统调用:从一个子站或另一个应用系统,通过代码直接登录到 DedeCMS 的主站,实现用户状态的同步。
- API 接口调用:提供一个标准的 URL 接口,允许外部应用(如手机 App、小程序、前端单页应用)通过传递特定参数(如用户名、密码、Token)来获取登录凭证,实现免登录。
下面我将分别针对这两种场景,提供 DedeCMS 5.7 的具体实现方法。
内部系统代码免登录(最常用)
这是最直接、最安全的方式,核心思路是:直接在 PHP 代码中模拟 DedeCMS 的登录流程,设置 Session 和 Cookie,从而绕过前台登录页面。
实现步骤
-
找到核心登录文件 DedeCMS 的前台登录逻辑主要在
/member/index_do.php文件中,我们需要研究这个文件是如何处理登录请求的。 -
分析登录逻辑 打开
/member/index_do.php,你会发现它通过一个switch语句来处理不同的操作,case 'login':就是处理登录的分支。 在这个分支里,核心代码是:
(图片来源网络,侵删)// ... 其他代码 $dsql->Execute('me',"SELECT * FROM `#@__member` WHERE userid='$userid' AND pwd='$pwd'"); $row = $dsql->GetArray(); if(!is_array($row)) { ShowMsg('用户名或密码错误!', '-1'); exit(); } // ... 其他验证代码(如审核状态等) // 登录成功,设置 Session 和 Cookie $uid = $row['mid']; $pwd = $row['pwd']; $loginsum = $loginsum + 1; $maintime = time(); $ip = GetIP(); // 更新最后登录信息 $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET logintime='$maintime',loginip='$ip',loginsum='$loginsum' WHERE mid='$uid'"); // 设置登录凭证 $safecode = substr(md5($cfg_cookie_encode.$pwd), 0, 16); $dede_logintime = $maintime; // 设置 Cookie PutCookie('DedeUserID', $uid, 3600 * 24 * 7); PutCookie('DedeLoginTime', $dede_logintime, 3600 * 24 * 7); PutCookie('DedeLoginTime', $dede_logintime, 3600 * 24 * 7); PutCookie('SESSID', session_id(), 3600 * 24 * 7); // ... 跳转逻辑从上面的代码可以看出,登录成功的关键在于:
- 验证用户名和密码。
- 获取用户
mid。 - 调用
PutCookie()函数设置三个关键的 Cookie:DedeUserID,DedeLoginTime,SESSID。
-
编写免登录代码 我们可以在任何需要的地方(比如另一个应用的入口文件)编写代码来模拟这个过程。
示例代码:
auto_login.php<?php // 引入 DedeCMS 的核心文件 // 注意:根据你的实际目录结构调整路径 define('DEDEINC', dirname(__FILE__) . '/include'); require_once(DEDEINC . '/dedev2config.php'); require_once(DEDEINC . '/common.inc.php'); require_once(DEDEINC . '/userlogin.class.php'); require_once(DEDEINC . '/datalistcp.class.php'); require_once(DEDEINC . ' /typelink.class.php'); require_once(DEDEMEMBER . '/config.php'); // 1. 准备登录信息 $target_username = 'your_username'; // 要登录的用户名 $target_password = 'your_password'; // 要登录的密码(明文或MD5,根据你的系统决定) // 2. 连接数据库并验证用户 $dsql = new DedeSql(false); $row = $dsql->GetOne("SELECT mid, pwd, uname FROM `#@__member` WHERE userid='$target_username'"); if (!is_array($row)) { die('用户不存在!'); } // 3. 验证密码 // DedeCMS 存储的密码是 MD5(密码 + 安全码),安全码在 dedev2config.php 中定义 // 如果你的密码是明文,需要这样处理: $pwd_encode = substr(md5($target_password . $cfg_cookie_encode), 0, 32); if ($row['pwd'] != $pwd_encode) { die('密码错误!'); } // 4. 登录成功,设置 Session 和 Cookie $uid = $row['mid']; $loginsum = $row['loginsum'] + 1; $maintime = time(); $ip = GetIP(); // 更新最后登录信息(可选) $dsql->ExecuteNoneQuery("UPDATE `#@__member` SET logintime='$maintime',loginip='$ip',loginsum='$loginsum' WHERE mid='$uid'"); // --- 核心部分:设置登录凭证 --- // 设置 Session $_SESSION['uid'] = $uid; $_SESSION['dlogin'] = 1; // 设置 Cookie PutCookie('DedeUserID', $uid, 3600 * 24 * 7); PutCookie('DedeLoginTime', $maintime, 3600 * 24 * 7); // PutCookie('SESSID', session_id(), 3600 * 24 * 7); // session_id() 可能已经存在,可以不重复设置 // 5. 跳转到会员中心或指定页面 echo "登录成功!正在跳转..."; header("Location: /member/"); exit(); ?>
如何使用
- 将上面的代码保存为
auto_login.php文件,并放到你的 DedeCMS 根目录下。 - 修改
$target_username和$target_password为你要登录的用户信息。 - 访问
http://你的域名/auto_login.php,脚本会自动完成登录并跳转到会员中心。
对外提供 API 免登录接口
这种方式适用于前后端分离架构,或者为第三方应用提供登录服务,核心思路是:创建一个独立的 PHP 文件,接收外部请求,验证参数,如果验证通过,则生成并返回一个登录凭证(如 Token 或 Session ID),前端拿到凭证后再去访问需要登录的 DedeCMS 页面。
实现步骤
-
创建 API 接口文件 在 DedeCMS 根目录创建一个新文件,
api/login.php。 -
编写 API 逻辑 这个文件将负责接收请求、验证参数、处理登录并返回 JSON 格式的结果。
示例代码:
api/login.php<?php header('Content-Type: application/json; charset=utf-8'); // 引入 DedeCMS 核心文件 define('DEDEINC', dirname(dirname(__FILE__)) . '/include'); require_once(DEDEINC . '/dedev2config.php'); require_once(DEDEINC . '/common.inc.php'); require_once(DEDEMEMBER . '/config.php'); // 1. 获取 POST 数据 $input = file_get_contents('php://input'); $data = json_decode($input, true); if (!$data || !isset($data['username']) || !isset($data['password'])) { echo json_encode(['code' => 400, 'msg' => '用户名和密码不能为空']); exit; } $username = $data['username']; $password = $data['password']; // 2. 连接数据库并验证用户 $dsql = new DedeSql(false); $row = $dsql->GetOne("SELECT mid, pwd, uname FROM `#@__member` WHERE userid='$username'"); if (!is_array($row)) { echo json_encode(['code' => 401, 'msg' => '用户不存在']); exit; } // 3. 验证密码 $pwd_encode = substr(md5($password . $cfg_cookie_encode), 0, 32); if ($row['pwd'] != $pwd_encode) { echo json_encode(['code' => 402, 'msg' => '密码错误']); exit; } // 4. 登录成功,生成凭证 // 这里我们直接返回用户信息,由前端自行处理(如存储 Token) // 更安全的做法是生成一个临时的 Token 并存入数据库,然后返回这个 Token $response = [ 'code' => 200, 'msg' => '登录成功', 'data' => [ 'uid' => $row['mid'], 'username' => $row['uname'], 'token' => md5($row['mid'] . time() . $cfg_cookie_encode), // 示例 Token,实际应用中应更复杂并设置有效期 'login_time' => time() ] ]; echo json_encode($response); exit; ?> -
前端如何调用 前端应用(如 Vue.js, React, jQuery AJAX)通过 POST 请求调用这个接口。
前端调用示例 (JavaScript/jQuery)
$(document).ready(function() { $('#loginForm').on('submit', function(e) { e.preventDefault(); var username = $('#username').val(); var password = $('#password').val(); $.ajax({ url: '/api/login.php', type: 'POST', contentType: 'application/json', data: JSON.stringify({ username: username, password: password }), success: function(response) { if (response.code === 200) { // 登录成功,存储 Token localStorage.setItem('dede_token', response.data.token); localStorage.setItem('dede_uid', response.data.uid); alert('登录成功!'); // 跳转到需要登录的页面 // window.location.href = '/member/index.php'; } else { alert(response.msg); } }, error: function() { alert('请求失败,请检查网络!'); } }); }); }); -
在 DedeCMS 中验证 Token 为了保护需要登录才能访问的页面,你需要在页面的头部加入验证逻辑。
示例:在
/member/index.php头部加入验证// 在 require_once(dirname(__FILE__)."/config.php"); 之后加入 if (isset($_SERVER['HTTP_X_DEDE_TOKEN']) || isset($_REQUEST['token'])) { $token = isset($_SERVER['HTTP_X_DEDE_TOKEN']) ? $_SERVER['HTTP_X_DEDE_TOKEN'] : $_REQUEST['token']; $uid = isset($_REQUEST['uid']) ? $_REQUEST['uid'] : (isset($_SERVER['HTTP_X_DEDE_UID']) ? $_SERVER['HTTP_X_DEDE_UID'] : ''); // 这里应该有一个验证 Token 是否有效且与 UID 匹配的逻辑 // 从数据库或缓存中查询 Token if ($token && $uid) { // 简单示例:直接设置登录状态,实际应用中需要更严格的验证 $_SESSION['uid'] = $uid; $_SESSION['dlogin'] = 1; PutCookie('DedeUserID', $uid, 3600 * 24 * 7); PutCookie('DedeLoginTime', time(), 3600 * 24 * 7); } else { header("HTTP/1.1 401 Unauthorized"); echo json_encode(['code' => 403, 'msg' => 'Token 无效或已过期']); exit; } } else { // 如果不是 API 请求,则走正常的 Session/Cookie 验证逻辑 // ... 原有的 DedeCMS 登录验证代码 ... }
安全注意事项
- HTTPS:如果提供对外 API 接口,必须使用 HTTPS,防止密码和 Token 在传输过程中被窃听。
- 密码安全:永远不要在前端直接传输明文密码,即使使用 HTTPS,也应考虑在后端对密码进行加盐哈希后再比对。
- 防暴力破解:API 接口应加入频率限制(Rate Limiting),例如限制一个 IP 每分钟最多尝试登录 5 次,防止暴力破解。
- Token 有效期:API 返回的 Token 应设置较短的有效期,并提供刷新 Token 的机制。
- 输入过滤:务必对所有用户输入进行过滤和转义,防止 SQL 注入等攻击,DedeCMS 的
$dsql->GetOne()已经做了部分处理,但养成良好习惯很重要。
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 内部代码免登录 | 实现简单、直接、安全(不暴露登录逻辑) | 仅适用于内部系统,无法为外部服务 | 子站同步登录、后台管理系统操作前台 |
| API 免登录接口 | 灵活、标准、前后端分离、可扩展性强 | 实现复杂、需要处理 Token/Session 状态、安全性要求高 | 手机 App、小程序、第三方应用、前后端分离项目 |
对于大多数 DedeCMS 5.7 场景一(内部代码免登录) 是最常用且最直接的解决方案,如果你正在构建现代化的应用,场景二(API 接口) 则是更符合技术趋势的选择。
