nenoNaninu / TypedSignalR.Client.DevTools

SignalR development tools inspired by SwaggerUI.
MIT License
47 stars 3 forks source link

[feature] Allow fetching or injecting access token #42

Open sommmen opened 1 year ago

sommmen commented 1 year ago

Hello,

Cool tools for SignalR you have here!

I don't really want to have to input my jwt token everytime im refreshing, it would be cool to allow for the token to come from a cookie or something. In other words; to have the dashboard automatically log in with a token.

I'm using other development related dashboarding libraries, so i'll detail how i got this working below. Basically my front-end manages an access token and saves it into local storage. Then i have various ways of loading that token into third party dashboards.

Swagger (NSwsag)

Needs no introduction.

The front end sets a cookie called token. And then i inject a custom js script into the dashboard of swagger. This sets the AT in a local storage item.

authservice.ts

document.cookie = `token=${auth.token};domain=${hostname}; SameSite=None; Secure`;

Startup.cs

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "OPG WebApi");
    c.EnablePersistAuthorization();
    c.InjectJavascript("/swagger-ui/custom.js"); // <--
});

custom.js:

/* https://stackoverflow.com/a/25346429/4122889 */
function getCookie(name) {
    function escape(s) { return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, "\\$1"); }
    var match = document.cookie.match(RegExp("(?:^|;\\s*)" + escape(name) + "=([^;]*)"));
    return match ? match[1] : null;
}

(function () {
    console.log("custom.js is loaded.");

    var token = getCookie("token");

    if (token) {
        var authObj = {
            Bearer: {
                name: "Bearer",
                schema: {
                    type: "http",
                    description: "Enter JWT Bearer token **_only_**",
                    scheme: "bearer",
                    bearerFormat: "JWT"
                },
                value: token
            }
        }
        localStorage.setItem("authorized", JSON.stringify(authObj));
    }
})();

Hangfire (background job scheduling)

https://docs.hangfire.io/en/latest/configuration/using-dashboard.html

The dashboard uses a simple cookie to save the JWT bearer so my Front-end simply sets the cookie via JS.

Serilog-ui (web view for the serilog logging library)

https://github.com/serilog-contrib/serilog-ui

I actually implemented parts of this feature myself in serilog-ui. In this case we set the token in session storage from the front-end, but also allow fetching the cookie (because why not) via custom script.

authservice.ts

// serilog-ui. Since this uses a session, this should be opened on the same page, or else this won't work.
sessionStorage.setItem('serilogui_token', `Bearer ${auth.token}`)

startup.cs

app.UseSerilogUi(options =>
{
    options.HomeUrl = env.IsDevelopment() ? "http://localhost:4200/" : "https://opg.systems/";
    options.InjectJavascript("/serilog-ui/custom.js", injectInHead: true);
    options.Authorization = new()
    {
        AuthenticationType = AuthenticationType.Jwt,
        Filters = new List<IUiAuthorizationFilter> { new OPGUiAuthorizationFilter() }
    };
});

custom.js

/* https://stackoverflow.com/a/25346429/4122889 */
function getCookie(name) {
    function escape(s) { return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, "\\$1"); }
    var match = document.cookie.match(RegExp("(?:^|;\\s*)" + escape(name) + "=([^;]*)"));
    return match ? match[1] : null;
}

(function () {
    console.log("custom.js is loaded.");

    var token = getCookie("token");

    if (token) {
        sessionStorage.setItem("serilogui_token", 'Bearer ' + token);
    }
})();

Proposal

Let me know if this is something you'd be interested in. It would sure help me out.

nenoNaninu commented 1 year ago

Thanks for the interesting feature request. It would be useful to be able to skip entering the JWT. However, to realize this feature in 'TypedSignalR.Client.DevTools' will take time as it needs to be well considered and designed.

sommmen commented 1 year ago

Okay when I have some time I might take a crack at this.