如何用PHP代码实现第三方登录集成_PHP第三方登录集成(如OAuth)实现教程

2 02 2 年,我在北京做项目,搞这个第三方登录,真是折腾。
当时也懵,怎么弄的来着?哦对,先去 Google 开发者控制台,注册个应用,搞个 ClientID 和 ClientSecret,记下来,别丢了。
像这样:
php // config.php return [ 'google' => [ 'client_id' => 'YOUR_GOOGLE_CLIENT_ID', 'client_secret' => 'YOUR_GOOGLE_CLIENT_SECRET', 'redirect_uri' => 'https://yoursite.com/auth/callback.php' ] ];
然后,用户点登录按钮,跳转到 Google 授权页。
这个跳转,代码是这么写的:
php // login.php $config = include 'config.php'; $authorizationUrl = "https://accounts.google.com/o/oauth2 /v2 /auth?" . http_build_query([ 'client_id' => $config['google']['client_id'], 'redirect_uri' => $config['google']['redirect_uri'], 'response_type' => 'code', 'scope' => 'email profile', // 请求用户邮箱和基本信息 'state' => bin2 hex(random_bytes(1 6 )) // 防止 CSRF 攻击 ]); header("Location:$authorizationUrl"); exit();
跳过去了,Google 给个 code 回来,然后要换 token。
回调脚本这么搞:
php // callback.php $config = include 'config.php'; session_start(); // 验证 state 参数(可选) if (!isset($_GET['code']) || empty($_GET['state']) || $_GET['state'] !== $_SESSION['oauth_state']) { die('授权失败或 CSRF 攻击'); }
// 用 cURL 请求令牌端点 $tokenUrl = 'https://oauth2 .googleapis.com/token'; $postData = [ 'code' => $_GET['code'], 'client_id' => $config['google']['client_id'], 'client_secret' => $config['google']['client_secret'], 'redirect_uri' => $config['google']['redirect_uri'], 'grant_type' => 'authorization_code' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $tokenUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $tokenData = json_decode($response, true); if (!isset($tokenData['access_token'])) { die('获取令牌失败'); } $accessToken = $tokenData['access_token'];
拿到 token,再调用 Google 的用户信息 API,搞点用户资料:
php // 继续 callback.php $userInfoUrl = 'https://www.googleapis.com/oauth2 /v3 /userinfo'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $userInfoUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization:Bearer$accessToken"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $userInfo = json_decode(curl_exec($ch), true); curl_close($ch); if (!isset($userInfo['email'])) { die('获取用户信息失败'); } $thirdPartyId = $userInfo['sub']; // Google 的唯一用户 ID $email = $userInfo['email']; $name = $userInfo['name'] '匿名用户';
最后,看看本地有没有这个用户,没有就新建一个:
php // 继续 callback.php $pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'username', 'password'); // 查询是否已绑定 $stmt = $pdo->prepare("SELECT id FROM users WHERE third_party_id=? AND platform='google'"); $stmt->execute([$thirdPartyId]); $user = $stmt->fetch(); if ($user) { // 用户已存在,更新登录时间 $_SESSION['user_id'] = $user['id']; $pdo->prepare("UPDATE users SET last_login=NOW() WHERE id=?")->execute([$user['id']]); } else { // 创建新用户 $stmt = $pdo->prepare("INSERT INTO users(email,name,third_party_id,platform,created_at)VALUES(?,?,?,'google',NOW())"); $stmt->execute([$email, $name, $thirdPartyId]); $_SESSION['user_id'] = $pdo->lastInsertId(); } // 跳转到首页 header("Location:/"); exit();
搞完这些,用户就登录上了。
安全性要注意,HTTPS 用上,state 参数验证,ClientSecret 别乱放。
2 02 2 年,北京那项目,就这样搞的。
可能我偏激,觉得这流程真麻烦。

php代码如何实现ip限制

说实话,这个IP限制在PHP里做啊,挺简单的。
你先得知道用户从哪儿来的,对吧?
php $ipAddress = $_SERVER['REMOTE_ADDR'];
这是最基础的,直接拿用户的IP。
但要注意啊,有些用户可能走代理,这时候直接拿REMOTE_ADDR就不准了。
比如你看到HTTP_X_FORWARDED_FOR,那得先看看这个:
php function getClientIP() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { return $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]; } return $_SERVER['REMOTE_ADDR']; }
这个函数是专门处理代理的。
HTTP_CLIENT_IP是直接连接你服务器的IP,HTTP_X_FORWARDED_FOR是代理转发的原始IP,一般取第一个就行。

然后是白名单,比如管理员就放行:
php $allowedIps = ['1 9 2 .1 6 8 .1 .1 ', '1 0.0.0.5 ']; if (!in_array($ipAddress, $allowedIps)) { header('HTTP/1 .0 4 03 Forbidden'); exit('Access Denied'); }
没在白名单就直接拦住,返回4 03
再高级点,你可以限制IP段。
比如公司内网1 9 2 .1 6 8 .1 .0/2 4 ,这样写:
php function isIpInRange($ip, $range) { list($subnet, $bits) = explode('/', $range); $ip = ip2 long($ip); $subnet = ip2 long($subnet); $mask = -1 << (3 2
$bits); return ($ip & $mask) == ($subnet & $mask); }
if (!isIpInRange($ipAddress, '1 9 2 .1 6 8 .1 .0/2 4 ')) { header('HTTP/1 .0 4 03 Forbidden'); exit; }
这个函数是检查IP是不是在某个网段里。
比如1 9 2 .1 6 8 .1 .1 00,和1 9 2 .1 6 8 .1 .0/2 4 比,肯定在。

黑名单也是类似:
php $blacklist = ['1 2 3 .4 5 .6 7 .8 9 ', '9 8 .7 6 .5 4 .3 2 ']; if (in_array($ipAddress, $blacklist)) { header('HTTP/1 .0 4 03 Forbidden'); exit('Your IP is blocked'); }
在黑名单就直接拦。

不过啊,这种硬编码的麻烦,改起来烦。
我推荐用数据库动态管理:
php $pdo = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass'); $stmt = $pdo->prepare("SELECT type FROM ip_restrictions WHERE ip=?"); $stmt->execute([$ipAddress]); $result = $stmt->fetch(); if (($result && $result['type'] == 'deny') || (!$result && !in_array($ipAddress, $allowedIps))) { header('HTTP/1 .0 4 03 Forbidden'); exit; }
数据库里有个表,存IP和类型(allow/deny)。
查一下这个IP是放行还是禁止。

实际用的话,你可以在每个页面开头加这个检查:
php require_once 'ip_security.php';
或者封装成类:
php class IPSecurity { public function checkAccess() { // 这里放检查逻辑 } } $security = new IPSecurity(); $security->checkAccess();
还有几个要注意的:
1 . 代理处理:上面那个getClientIP()函数就是 2 . 日志记录:失败尝试可以记下来 3 . 性能优化:IP列表多的话,放Redis里查快 4 . IPv6 :现在很多手机是IPv6 ,得支持 5 . 注意事:动态IP(像家宽带)会变,NAT也把多个IP搞成一样的
总之啊,这些方法都能用,怎么组合看你自己。
核心逻辑封装成类比较好,以后改方便。
高安全的话,服务器层面(比如Nginx)再加一层限制更稳。

如何在html中嵌入php

上周 我那个朋友问的php嵌入的问题
两种方法
1 . 标准标签
<?php echo date('Y-m-d H:i:s'); ?>
<?php $user = "访客"; if(isset($_GET['name'])) { $user = specialchars($_GET['name']); } echo "

欢迎,".$user."!

"; ?>
每个块要闭合
echo或print输出
2 . 短标签
<?php echo $_SERVER['REMOTE_ADDR']; ?>
<?php echo rand(1 , 1 00); ?>
简单输出用短标签
服务器要支持
<?php include 'header.php'; ?>
<?php include 'footer.php'; ?>
注意事项
文件名必须是.php
用支持php的服务器
建议和php分离开
用户输入要过滤
<?php specialchars($_GET['input']); ?>
开发环境显示错误
<?php error_reporting(E_ALL); ini_set('display_errors', 1 ); ?>
进阶用法
条件注释
<?php $isMobile = true; ?>
<!-
响应式内容 -->

循环
<?php foreach($products as $product): ?>
  • <?php echo $product['name']; ?>-<?php echo number_format($product['price'], 2 ); ?> <?php endforeach; ?>
    模板继承
    header.php
    <?php include 'header.php'; ?>
    footer.php
    <?php include 'footer.php'; ?>
    最后 根据项目选方法 小项目短标签 大项目标准标签+模板
    算了

    PHP如何实现二维码生成_二维码生成代码编写详解

    哎,这个PHP生成二维码啊,我之前搞的时候也头大。
    主要是靠那个endroid/qr-code库,确实好用。

    首先,你得用Composer装它。
    就在项目根目录敲命令:composer require endroid/qr-code。
    然后,代码里面就这么写:
    php <?php require 'vendor/autoload.php';
    use Endroid\QrCode\QrCode; use Endroid\QrCode\Writer\PngWriter;
    $qrCode = QrCode::create('https://www.example.com') ->setErrorCorrectionLevel('high') ->setSize(3 00) ->setMargin(1 0);
    $writer = new PngWriter(); header('Content-Type: ' . $qrCode->getContentType()); echo $writer->write($qrCode)->getString(); ?>
    这个是最基础的,生成一个PNG格式的二维码。
    URL是核心,别写错。

    然后,你想加Logo啊,改颜色啊,都得调整参数。

    加Logo的话,关键是要设高纠错级别,比如'high'。
    Logo大小不能太大,我试过,不能超过二维码总面积的3 0%,不然扫不出来。
    代码是这样:
    php $result = Builder::create() ->data('https://your-company.com') ->errorCorrectionLevel('high') ->size(3 00) ->margin(1 0) ->logoPath(__DIR__ . '/logo.png') ->logoResizeToWidth(8 0) ->logoResizeToHeight(8 0) ->logoPunchoutBackground(true) ->writer(new PngWriter()) ->build();
    颜色自定义要注意,前景色和背景色得有够对比。
    比如蓝底黄字,或者纯黑纯白。
    代码:
    php use Endroid\QrCode\Color\Color;
    $result = Builder::create() ->data('https://colorful-qr.com') ->foregroundColor(new Color(0, 0, 2 5 5 )) ->backgroundColor(new Color(2 5 5 , 2 5 5 , 0)) ->build();
    搞这些的时候,肯定会有问题。
    最常见的是扫不出来。

    一个是纠错级别不够,特别是加了Logo之后,必须用'high'。
    数据量太大会不行,URL太长就缩短点,或者用那种短链接服务。

    颜色对比度不够也扫不了,别搞什么浅蓝配浅绿的,肯定不行,就用黑白的或者红黄的这种。

    有时候扫失败,是二维码尺寸太小,或者边距不够。
    我试过,尺寸得够大,物理尺寸最好2 cm×2 cm,输出分辨率3 00dpi以上。
    边距也得分设,至少1 0像素。

    输出格式也得注意,PNG最好,别用JPG,压缩多了扫不出来。

    Logo太大也扫不了,我试过,不能超过3 0%,形状规则点,圆形方形都行,非透明的背景用logoPunchoutBackground(true)处理一下。

    选库的时候,我推荐endroid/qr-code,功能全,支持格式多,跟Laravel这种框架也能无缝集成。
    如果项目里依赖限制特别严,就用phpqrcode,轻便点。

    排查问题的时候,就从最简单的黑白二维码开始试,一步步加东西。
    参数对不对,纠错级别呢,尺寸和边距呢,颜色够不够对比度?最后用那种在线的扫码工具扫一扫,看看是哪出错了。

    总之,搞这个,多试几次就好了。