Skip to content

SignIn with OAuth? #6

Closed
Closed
@gaetandezeiraud

Description

@gaetandezeiraud

How to SignIn with OAuth providers? Like Google, Facebook, etc...
I tried on my side, but doesn't found a solution to a problem, Supabase return the access_token in the fragment part of the URL... So I can't get it with a HttpListener for example.

Here the code (not a clean code):

using com.example;
using System;
using System.Threading.Tasks;
using Supabase.Gotrue;
using Supabase.Gotrue.Exceptions;
using TMPro;
using UnityEngine;
using static Supabase.Gotrue.Constants;
using System.Net;

public class SignInWithGoogle : MonoBehaviour
{
    [SerializeField] private string redirectUrl = "http://localhost:3000/";
    private string pkce;

    // Public Unity References
    public TMP_Text ErrorText = null!;
    public SupabaseManager SupabaseManager = null!;

    // Private implementation
    private bool _doSignIn;
    private bool _doSignOut;

    // Unity does not allow async UI events, so we set a flag and use Update() to do the async work
    public void SignIn()
    {
        _doSignIn = true;
    }

    // Unity does not allow async UI events, so we set a flag and use Update() to do the async work
    public void SignOut()
    {
        _doSignOut = true;
    }

    private async void Update()
    {
        // Unity does not allow async UI events, so we set a flag and use Update() to do the async work
        if (_doSignOut)
        {
            _doSignOut = false;
            await SupabaseManager.Supabase()!.Auth.SignOut();
            _doSignOut = false;
        }

        // Unity does not allow async UI events, so we set a flag and use Update() to do the async work
        if (_doSignIn)
        {
            _doSignIn = false;
            await PerformSignIn();
            _doSignIn = false;
        }
    }

    private void StartLocalWebserver()
    {
        HttpListener httpListener = new HttpListener();

        httpListener.Prefixes.Add("http://*:3000/");
        //httpListener.Prefixes.Add("http://127.0.0.1:3000/");
        //httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
        httpListener.Start();
        httpListener.BeginGetContext(new AsyncCallback(IncomingHttpRequest), httpListener);
    }

    private async void IncomingHttpRequest(IAsyncResult result)
    {
        Debug.Log("IncomingHttpRequest");

        HttpListener httpListener;
        HttpListenerContext httpContext;
        HttpListenerRequest httpRequest;
        HttpListenerResponse httpResponse;
        string responseString;

        // get back the reference to our http listener
        httpListener = (HttpListener)result.AsyncState;

        // fetch the context object
        httpContext = httpListener.EndGetContext(result);

        // the context object has the request object for us, that holds details about the incoming request
        httpRequest = httpContext.Request;

        var token = httpRequest.QueryString.Get("access_token");
        // string accessToken = Regex.Match(responseBody, @"access_token=([^#]+)").Groups[1].Value;
        Debug.Log("=====> " + httpRequest.Url.Fragment);

        // build a response to send an "ok" back to the browser for the user to see
        httpResponse = httpContext.Response;
        responseString = "<html><body><b>DONE!</b><br>(You can close this tab/window now)</body></html>";
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);

        // send the output to the client browser
        httpResponse.ContentLength64 = buffer.Length;
        System.IO.Stream output = httpResponse.OutputStream;
        output.Write(buffer, 0, buffer.Length);
        output.Close();


        try
        {
            Debug.Log("pkce: " + pkce);
            Debug.Log("Token: " + token);

            Session session = (await SupabaseManager.Supabase()!.Auth.ExchangeCodeForSession(pkce, token)!);
            ErrorText.text = $"Success! Signed Up as {session.User?.Email}";
        }
        catch (GotrueException goTrueException)
        {
            ErrorText.text = $"{goTrueException.Reason} {goTrueException.Message}";
            Debug.Log(goTrueException.Message, gameObject);
            Debug.LogException(goTrueException, gameObject);
        }
        catch (Exception e)
        {
            Debug.Log(e.Message, gameObject);
            Debug.Log(e, gameObject);
        }

        httpListener.Stop();
    }

    // This is where we do the async work and handle exceptions
    private async Task PerformSignIn()
    {
        try
        {
            var providerAuth = (await SupabaseManager.Supabase()!.Auth.SignIn(Provider.Google))!;
            var signInUrl = providerAuth.Uri.ToString();
            pkce = providerAuth.PKCEVerifier;

            Debug.Log("Destination host: " + signInUrl);

            StartLocalWebserver();
            Application.OpenURL(signInUrl);
        }
        catch (GotrueException goTrueException)
        {
            ErrorText.text = $"{goTrueException.Reason} {goTrueException.Message}";
            Debug.Log(goTrueException.Message, gameObject);
            Debug.LogException(goTrueException, gameObject);
        }
        catch (Exception e)
        {
            Debug.Log(e.Message, gameObject);
            Debug.Log(e, gameObject);
        }
    }
}

And so, token is empty, also Debug.Log("=====> " + httpRequest.Url.Fragment);.
Any idea?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions