Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions trivialkart/trivialkart-auth-server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
build
npm-debug.log
.env
.DS_Store
143 changes: 143 additions & 0 deletions trivialkart/trivialkart-auth-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# **OpenID Account Linking Sample: PGS v1 to v2 Migration**

This sample project demonstrates how to implement a robust account linking system that survives the migration from **Google Play Games Services (PGS) v1** to **v2**.

It specifically addresses the scenario where you need to authenticate users against your own backend server while upgrading your Unity client from the deprecated v1 authentication flow to the new v2 flow.

## **🔑 The Core Concept: OpenID Consistency**

The most critical challenge in migrating from PGS v1 to v2 is ensuring that players do not lose their account progress. This sample solves this by relying on the **OpenID Connect `sub` (Subject) claim**.

### **How it works:**

1. **In PGS v1**: The client obtains an **ID Token** directly and sends it to the server. The server verifies it and extracts the `sub` (OpenID).
2. **In PGS v2**: The client obtains a **Server Auth Code**, sends it to the server, and the server exchanges it for an ID Token. The server extracts the `sub` (OpenID).

**Crucially, the `sub` value for a specific Google user is identical in both scenarios.**

By using this `sub` value as the key in your database (e.g., `google-123456789`), a user can start playing on v1, upgrade the app to v2, and your server will recognize them as the exact same user.

## **📂 Files Overview**

* **[server.js](/trivialkart/trivialkart-auth-server/server.js)**: A Node.js/Express backend.
* **Endpoint `/verify_and_link_google`**: Handles the v1 flow (verifies ID Token directly).
* **Endpoint `/exchange_authcode_and_link`**: Handles the v2 flow (exchanges Auth Code for Token).
* **Logic**: Both endpoints resolve to the same `userDatabase` entry based on the `sub` claim.
* **[AuthManager.cs](/trivialkart/trivialkart-unity/Assets/Scripts/AuthManager.cs)**: A Unity C# script that manages the UI and Authentication logic.
* Uses Preprocessor Directives (`#if PGS_V1` / `#if PGS_V2`) to compile different logic for the different SDK versions.

## **🛠️ Prerequisites**

* **Unity 2020.3+**
* **Node.js** (v14+)
* **Google Cloud Console Project** with OAuth 2.0 Web Client Credentials.
* **Facebook App** (Optional: only required if testing Facebook linking features).

## **🚀 Backend Setup**

1. **Install Dependencies**:

```bash
npm install express google-auth-library jsonwebtoken dotenv axios
```

2. **Configure Environment**: Create a `.env` file in the same directory as `server.js`:

```env
WEB_CLIENT_ID=your-google-web-client-id.apps.googleusercontent.com
WEB_CLIENT_SECRET=your-google-web-client-secret
FB_APP_ID=your-facebook-app-id
FB_APP_SECRET=your-facebook-app-secret
JWT_SECRET=super-secret-key-for-your-game-jwt
```

3. **Note:** The `WEB_CLIENT_ID` must be the "Web application" Client ID from Google Cloud Console, **not** the Android Client ID.
4. **Run the Server**:

```bash
node server.js
```

## **🎮 Unity Client Setup**

This sample uses **Scripting Define Symbols** to switch between the v1 and v2 implementation without changing the code manually.

### **🧹 Clean Removal (Important)**

**⚠️ Backup your project before proceeding.**

When switching between versions (e.g., v1 to v2) or if you encounter dependency resolution errors, you **must** cleanly remove the installed plugin artifacts before importing the new package.

Delete the following folders from your Unity project's `Assets` directory:

1. `Assets/ExternalDependencyManager`
2. `Assets/GeneratedLocalRepo`
3. `Assets/GooglePlayGames`

*(Note: You may also need to check `Assets/Plugins` for residual Android/iOS libraries if errors persist.)*

### **Dependencies**

* **Common**
* **[Facebook SDK for Unity](https://developers.facebook.com/docs/unity/downloads)** (Optional)
* **For v1**:
* **[Google Play Games Plugin for Unity **v0.10.15**](https://github.com/playgameservices/play-games-plugin-for-unity/releases)**.
* **For v2**:
* **[Google Play Games Plugin for Unity **v2.1.0**](https://github.com/playgameservices/play-games-plugin-for-unity/releases)**.
* **[Google Sign-In Unity Plugin](https://github.com/googlesamples/google-signin-unity/releases)**.
*(Note: PGS v2 removes authentication methods, so the separate Google Sign-In plugin is required to retrieve Auth Codes.)*

### **Configuration Steps**

1. **Working scene**: Open the **[MockSignIn](/trivialkart/trivialkart-unity/Assets/Scenes/MockSignIn.unity)** Scene
2. **Allow HTTP Downloads:** In your **Player Settings** (*Edit > Project Settings > Player*), find the "Other Settings" tab. Ensure **Allow downloads over HTTP** is set to **Allowed in development builds**.
* *Note: This is only for testing with a local `http://` server. Production apps must use `https://`.*
3. **Set Server URL**: Find the `AuthManager` GameObject in the scene. Set the `Server Url` field in the Inspector to your local IP (e.g., `http://192.168.1.5:3000`).

### **Switching Versions**

To switch the active code path, go to **Project Settings > Player > Other Settings > Scripting Define Symbols**.

#### **Mode A: Simulating PGS v1 (Legacy)**

Add the symbol: `PGS_V1`

* **Behavior**: The script uses `PlayGamesPlatform.Instance.GetIdToken()` to get a token.
* **Server Endpoint**: Calls `/verify_and_link_google`.

#### **Mode B: Simulating PGS v2 (Migration Target)**

Add the symbol: `PGS_V2`

* **Behavior**: The script uses `GoogleSignIn.DefaultInstance.SignIn()` to get an **Auth Code**.
* **Server Endpoint**: Calls `/exchange_authcode_and_link`.

## **🧪 Testing the Migration**

1. **Start with PGS_V1**:
* Build the app with the `PGS_V1` symbol.
* (Use "Development Build" to enable the HTTP permissions set earlier).
* Login with Google.
* Note the "In-Game ID" displayed (e.g., `ingame-1001`).
* Increment the counter to save some data.
2. **Upgrade to PGS_V2**:
* Change the symbol to `PGS_V2`.
* (Ensure you have the Google Sign-In plugin installed and older PGS v1 files removed).
* Build and run the app again (simulating an app update).
* Login with Google.
3. **Verify**:
* The server logs will show `(PGS v2) Verified... Existing user linked to OpenID`.
* The client should receive the **exact same** In-Game ID (`ingame-1001`) and your previous count.

## **⚠️ Important Note on Client IDs**

For the **v2 Flow (Auth Code)** to work, you must configure the Google Sign-In plugin in Unity with your **Web Client ID**, not your Android Client ID.

```csharp
// Inside AuthManager.cs (v2 block)
GoogleSignIn.Configuration = new GoogleSignInConfiguration
{
WebClientId = "YOUR_WEB_CLIENT_ID_HERE", // Must match .env WEB_CLIENT_ID exactly
RequestAuthCode = true, // Critical for v2 backend linking
// ...
};
20 changes: 20 additions & 0 deletions trivialkart/trivialkart-auth-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "levelup_multilogin_server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Comment on lines +5 to +8

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The main entry points to index.js, but the server file is server.js. This should be corrected to avoid issues with tools that rely on this field. Additionally, adding a start script is a common convention that makes running the server easier (npm start).

Suggested change
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},

"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"axios": "^1.13.1",
"dotenv": "^17.2.3",
"express": "^5.1.0",
"google-auth-library": "^10.4.1",
"jsonwebtoken": "^9.0.2"
Comment on lines +14 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Several of the package versions listed in dependencies do not correspond to public releases on npm (e.g., axios, dotenv, express, google-auth-library). This will likely cause npm install to fail unless you are using a private registry. Please verify these versions and update them to valid public versions if applicable.

Example with current public versions:

"dependencies": {
  "axios": "^1.7.2",
  "dotenv": "^16.4.5",
  "express": "^4.19.2",
  "google-auth-library": "^9.11.0",
  "jsonwebtoken": "^9.0.2"
}
Suggested change
"axios": "^1.13.1",
"dotenv": "^17.2.3",
"express": "^5.1.0",
"google-auth-library": "^10.4.1",
"jsonwebtoken": "^9.0.2"
"axios": "^1.7.2",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"google-auth-library": "^9.11.0",
"jsonwebtoken": "^9.0.2"

}
}
Loading