在Concrete5搭建的企业内网中,如何通过Google登录请求额外权限?
解决方案:Concrete5 集成 Gmail 一键登录+自动授权+日历展示
嘿,我之前帮团队搭过类似的Concrete5内网系统,正好踩过不少坑,给你一套不用动核心文件的落地方案:
第一步:先搞定 Google OAuth2 应用配置
首先得在Google那边弄好授权凭据,不然Concrete5没法和Gmail对接:
- 去Google Cloud Console新建个项目,记得启用Google Calendar API(毕竟要访问个人日历)
- 创建OAuth2客户端ID,授权回调URL填你内网的回调地址,比如
https://your-intranet-domain.com/login/oauth2/callback - 把生成的Client ID和Client Secret存好,后面要用到
第二步:用自定义包扩展Concrete5登录流程
Concrete5绝对不建议直接改核心文件,升级会全丢,所以咱们做个自定义包来接管登录:
2.1 写个自定义登录控制器
在你的包目录(比如packages/gmail_login/)下创建controllers/login.php,代码如下:
<?php namespace Concrete\Package\GmailLogin\Controller; use Concrete\Core\Controller\Controller; use League\OAuth2\Client\Provider\Google; use Concrete\Core\User\User; class Login extends Controller { public function oauth() { // 替换成你自己的Google凭据 $provider = new Google([ 'clientId' => '你的Google Client ID', 'clientSecret' => '你的Google Client Secret', 'redirectUri' => 'https://your-intranet-domain.com/login/oauth2/callback', ]); // 还没拿到授权码?直接跳Google授权页(自动触发权限请求) if (!isset($_GET['code'])) { $authUrl = $provider->getAuthorizationUrl([ 'scope' => [ 'email', 'profile', 'https://www.googleapis.com/auth/calendar.readonly' // 要日历只读权限,按需调整 ] ]); $_SESSION['oauth2state'] = $provider->getState(); header('Location: ' . $authUrl); exit; } // 处理Google回调回来的授权码 else { // 验证state防CSRF,这个不能省 if (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { unset($_SESSION['oauth2state']); $this->redirect('/login', 'error'); } // 获取访问令牌 $token = $provider->getAccessToken('authorization_code', [ 'code' => $_GET['code'] ]); // 拿到用户的Gmail信息 $googleUser = $provider->getResourceOwner($token); $userEmail = $googleUser->getEmail(); // 检查Concrete5里有没有这个用户 $c5User = User::getByEmail($userEmail); if ($c5User && $c5User->isRegistered()) { // 自动登录这个用户 $c5User->login(); // 把令牌存在用户属性里,后面调用日历API要用 $c5User->setUserAttribute('google_access_token', $token->getToken()); $c5User->setUserAttribute('google_refresh_token', $token->getRefreshToken()); // 直接跳首页 $this->redirect('/'); } else { // 内网一般只允许公司邮箱,所以加个域名检查 if (str_ends_with($userEmail, '@你的公司域名.com')) { // 自动创建新用户 $newUser = new User(); $newUser->create([ 'uName' => $userEmail, 'uEmail' => $userEmail, 'uFullName' => $googleUser->getName() ]); $newUser->login(); $newUser->setUserAttribute('google_access_token', $token->getToken()); $this->redirect('/'); } else { // 非公司邮箱直接踢回登录页 $this->redirect('/login', 'invalid_domain'); } } } } }
2.2 替换默认登录入口
把你主题里的登录按钮链接改成自定义的OAuth地址:
<a href="/index.php/login/oauth" class="btn btn-primary">用Gmail一键登录</a>
要是想更彻底,直接把Concrete5默认的登录页面模板改成自动跳转这个OAuth地址,用户点登录就直接触发授权,完全不用填账号密码。
第三步:展示用户的个人日历
登录后用户已经有了Google的访问令牌,咱们可以做个自定义区块或者页面类型来加载日历:
<?php $currentUser = new User(); $accessToken = $currentUser->getUserAttribute('google_access_token'); if ($accessToken) { $client = new Google\Client(); $client->setAccessToken($accessToken); // 令牌过期了?用刷新令牌自动更新 if ($client->isAccessTokenExpired()) { $refreshToken = $currentUser->getUserAttribute('google_refresh_token'); $client->fetchAccessTokenWithRefreshToken($refreshToken); $newTokenData = $client->getAccessToken(); $currentUser->setUserAttribute('google_access_token', $newTokenData['access_token']); // 刷新令牌可能会变,要存回去 $currentUser->setUserAttribute('google_refresh_token', $newTokenData['refresh_token'] ?? $refreshToken); } // 调用Calendar API拿事件 $calendarService = new Google\Service\Calendar($client); $events = $calendarService->events->listEvents('primary', [ 'maxResults' => 10, 'orderBy' => 'startTime', 'singleEvents' => true, 'timeMin' => date('c'), ]); // 渲染日历事件 foreach ($events->getItems() as $event) { $eventStart = $event->start->dateTime ?? $event->start->date; echo "<div class='calendar-event mb-3'>"; echo "<h4 class='mb-1'>" . h($event->getSummary()) . "</h4>"; echo "<p class='text-muted'>" . h($eventStart) . "</p>"; echo "</div>"; } } else { echo "<p class='text-warning'>请先登录以查看个人日历</p>"; }
几个关键提醒
- 绝对别改核心文件:用自定义包和主题模板扩展,不然Concrete5升级后你的修改全没了
- 权限锁死:一定要加公司邮箱域名检查,防止外人登录内网
- 令牌管理:把Google的令牌存在用户自定义属性里,方便后续调用API,还要处理令牌过期自动刷新
- 安全不能省:OAuth的state参数一定要验证,防CSRF攻击
- 测试阶段:在Google Cloud Console里加测试用户,不然开发时可能会遇到授权限制
这样一套下来,用户点击登录就直接跳Google授权页,授权完自动登录Concrete5并跳首页,后续还能直接看个人日历,完全符合你的需求。
内容的提问来源于stack exchange,提问作者TheLittleStarWarrior
相关产品推荐
相关产品推荐

