首页 > 解决方案 > Unity WebGL PHP 数据库操作

问题描述

我正在尝试让 WebGL 统一游戏更新 MySQL 数据库,基本上,我想让它这样当用户登录网站并击败统一游戏时,他们会在网站上的个人资料上解锁徽章。

所以我写了一个更新数据库的PHP脚本来解锁徽章,然后我写了一个C#脚本给Unity游戏发送一个post请求到PHP脚本。我对这个解决方案的问题是,像邮递员这样的任何外部网站都可以发送相同的发布请求,而玩家不需要真正击败游戏来解锁徽章。

然后我想也许我应该将数据库凭据放在 C# 脚本中并直接从那里编辑数据库,但我在网上看到这是一个安全问题,因为玩家可以反编译游戏并获取数据库的登录凭据。

所以我做了一些研究,并认为我的解决方案可能是 PHP 页面上的 CSRF,那么也许我可以将令牌传递给统一游戏?我能够让 PHP 与添加到其中的 CSRF 一起工作,但我不知道如何让统一游戏能够发送带有令牌的发布请求以解锁网站上的徽章。

让统一游戏直接编辑数据库会不会有安全问题?任何有关如何解决此问题的建议将不胜感激,如果有任何帮助,我在下面发布了相关文件,但我认为这更多是一个概念性问题。

解锁卡2.php

<?php
 require "header.php";

 //check if user is logged in
 if(isset($_SESSION['userId'])){

    //create key for hash_hmac function
    if(empty($_SESSION['key']))
        $_SESSION['key'] = bin2hex(random_bytes(32));

    //create CSRF token
    $csrf = hash_hmac('sha256', 'some random string', $_SESSION['key']);
    if (isset($_POST['submit'])) {

        if(hash_equals($csrf, $_POST['csrf'])) {
            echo '<form action="includes/unlockcard.inc.php" method="post">
            <button type="submit" name="unlock-submit">unlock card</button>
            </form>';
        }
        else{
            echo 'CSRF Token Failed';
        }
    }
 }
 ?>

 <html>
 <form method="POST" action ="unlockcard2.php">
 <input type="hidden" name="csrf" value="<?php echo $csrf ?>" >
 <input type="submit" name="submit" value="SUBMIT">
 </form>
 </html>

解锁卡.inc.php

<?php

$servername = "localhost";
$dBUsername = "root";
$dBPassword = "";
$dBName = "loginsystem";

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); //error reporting
$conn = mysqli_connect($servername, $dBUsername, $dBPassword, $dBName);

session_start();    
$sql = "UPDATE users SET card1 =? WHERE idUsers =?";
$stmt = $conn->prepare($sql);

$c = '1';
$i = $_SESSION['userId'];

$stmt->bind_param("ii", $c, $i); //bind variables
$stmt->execute(); //execute prepared statement


$stmt->close();
$conn->close();

卡片解锁器.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class cardUnlocker : MonoBehaviour
{
    string unlockCardURL = "http://localhost/phpstuff/includes/unlockcard.inc.php";

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(PostRequest(unlockCardURL));
    }

    // Update is called once per frame
    void Update()
    {

    }

    IEnumerator PostRequest(string url)
    {
        WWWForm form = new WWWForm();
        UnityWebRequest uwr = UnityWebRequest.Post(unlockCardURL, form);
        yield return uwr.SendWebRequest();

        if (uwr.isNetworkError)
        {
            Debug.Log("Error while sending: " + uwr.error);
        }
        else
        {
            Debug.Log("Received: " + uwr.downloadHandler.text);
        }
    }
}

标签: phpmysqlunity3d

解决方案


推荐阅读