Host-Side Widget Login

Client-Side Widget Integration and Authentication Example

This example illustrates a common pattern for integrating a secure widget within a main web application. It showcases user authentication on the main site, secure communication of an access token to an embedded widget via postMessage, and handling responses from the widget.

Overall Workflow

  1. Initial Setup: In the widget settings, you first enable host-side login and obtain your app_id and secret_key.

  2. The user enters an email address on the main site and attempts to log in.

  3. The main site's JavaScript generates a signature for the authentication request using the obtained app_id, secret_key, and current timestamp.

  4. The main site sends an authentication request (including app_id, email, timestamp, and the sign) to the backend API (https://api.giggle.pro/api/v1/app/auth/login).

  5. Upon successful authentication, the backend returns an access_token.

  6. The main site uses window.postMessage to send this access_token to the embedded widget within an iframe.

  7. The widget (running inside the iframe) processes the token, performs its own login, and sends back a login_result message to the main site.

  8. The main site updates its UI status and manages a "Logout" button based on the widget's response.

  9. A similar postMessage mechanism is used for logout.

spinner

Core Examples

The example relies on several key JavaScript functions and configurations:

1. Configuration Parameters (request_params)

These are the initial parameters used for the authentication request. You will obtain your app_id and secret_key by enabling host-side login within your widget's settings.

JavaScript

  • app_id: A unique identifier for your application, which you get from your widget's settings.

  • secret_key: Your application's secret key, also obtained from widget settings. Crucially, the comment in the code explicitly states: (NOTE: Do not leak this key, token should be generated by the backend and returned to the frontend). This is a critical security warning. Generating signatures with a secret_key directly in frontend JavaScript is highly insecure, as the key can be easily extracted by anyone inspecting the page.

  • email: The user's email, dynamically populated from the input form.

  • timestamp: The current time in Unix seconds, used to prevent replay attacks on the authentication request.

2. Signature Generation (generateSign)

This function creates an MD5 signature for the authentication request parameters.

JavaScript

  • Logic: The function filters out the sign parameter itself and any null/undefined values, sorts the remaining parameters by key, concatenates them into a string (e.g., "key1=value1,key2=value2"), appends ",key=YOUR_SECRET_KEY", and finally computes the uppercase MD5 hash of this composite string.

  • Security Risk: As mentioned for request_params, exposing the secret_key within this client-side function makes it vulnerable to theft and misuse.

3. Access Token Acquisition (getAccessToken)

This asynchronous function handles the authentication request to your backend.

JavaScript

  • Process: It prepares the request data, including the dynamically generated sign and timestamp, then sends a POST request to the /api/v1/app/auth/login endpoint.

  • Token Handling: If the authentication is successful and an access_token is received in the response, it calls postTokenToIframe to pass this token to the embedded widget.

4. Iframe Communication (postTokenToIframe, postLogoutToIframe, handleIframeMessage)

These functions manage the secure communication between the main page and the iframe using window.postMessage.

  • postTokenToIframe(token):

    • Constructs a message object { type: 'login', token: token }.

    • Sends this message to the iframe's content window using postMessage(message, 'https://app.giggle.pro'). The target origin (https://app.giggle.pro) is critical for security, ensuring the message is only sent to the intended recipient.

  • postLogoutToIframe():

    • Constructs a message object { type: 'logout' }.

    • Sends this message to the iframe.

  • handleIframeMessage(event):

    • Listens for messages coming from the iframe.

    • Security Check: It rigorously validates event.origin (event.origin must be https://app.giggle.pro) to prevent accepting messages from untrusted sources. This is crucial for preventing cross-site scripting (XSS) and other attacks.

    • Processes login_result and logout_result messages from the iframe, updating the UI accordingly.

5. UI Utilities (logEvent, showStatus, hideStatus)

These functions manage user feedback and debugging logs within the page.

  • logEvent(message, data): Appends formatted messages and data to a scrollable "Event Log" area, keeping a limited number of entries (50) to prevent memory issues.

  • showStatus(message, isError): Updates a status message element in the UI, coloring it red for errors and green for success.

  • hideStatus(): Hides the status message element.


Critical Security Warning

This example code directly exposes the secret_key (request_params.secret_key) and performs signature generation (generateSign) in frontend JavaScript. In a production environment, this is a severe security vulnerability. An attacker can easily inspect your frontend code, extract your secret_key, and then forge authenticated requests, potentially leading to unauthorized access or malicious actions.

Best Practice:

  • Always generate access tokens and cryptographic signatures (like the MD5 sign or JWT signatures) on your secure backend server.

  • The frontend should send user credentials (like email/password) to your backend.

  • Your backend then uses its securely stored secret_key to authenticate with the portal API and generate any necessary tokens or signatures.

  • Only the resulting token (e.g., the access_token for the widget, or a JWT) should be returned to the frontend.

  • This token can then be safely passed to the widget via postMessage.

By following this backend-only approach for sensitive operations, you protect your secret_key and maintain the integrity of your authentication flow.

Last updated