How to secure Keys in Javascript?

Dondon510 261 Reputation points
2022-07-02T01:26:07.907+00:00

I use APIKey, APISecret and Deployment to constant variables like below:

public const string Path = "/Deploy/Here";  
public const string APIKey = "xyzApIKeY";  
public const string APISecret = "zbcApISeCrEt";  

I call controller using ajax like below:

    $.ajax({  
                    type: 'POST',  
                    url: '@MyApp.Models.AppSettings.Application.Path' + '/Sales/Add_Update/' + '@Model.xData',  
                    data: fd,  
                    processData: false,  
                    contentType: false,  
                    headers: {  
                        apiKey: '@MyApp.Models.AppSettings.Application.APIKey',  
                        apiSecret: '@MyApp.Models.AppSettings.Application.APISecret'  
                    },  
                    success: function(result) {  
                          
                    },  
                    error: function(result) {  
                           
                    }  
                });  

everything (Path, APIKey, APISecret) are displayed clearly in javascript, any tips or idea on how to secure or hide it?

I need advice

thanks a lot in advance

Developer technologies ASP.NET ASP.NET Core
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2022-07-03T18:46:02.197+00:00

    If you are authenticating (looks like cookie) why does the client need an api key and secret?


6 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2022-07-02T18:05:20.243+00:00

    Php is just a different language to write your webapi in. Asp.net core is just fine (probably better than php)

    You want the user to authentication to your webapi and get a jwt bearer token. You can store the api key and secrecy in the token as claims, but they must be encrypted. The server must associate the authenticated user with the api and secret. But generally an api key and secret is a replacement for authentication, so I not sure there use.

    You should describe you security needs better, so a suggested solution matches.

    0 comments No comments

  2. Dondon510 261 Reputation points
    2022-07-03T00:51:35.677+00:00

    Hi @Bruce (SqlWork.com)

    We develop using ASP MVC Netcore 6, and this is my current use case:

    In Login Page, We use AJAX in Views/Login/Index.cshtml and call POST Users/Login (Controller/Action) with Anonymous attribute, in this stage, the API and Secret already exposed! (very bad) :(

    after they logged in, the users could see all of their Sales Achievement, in here the system would use /Views/Sales/Index.cshtml, and call GET Sales/Index with Authorize Attribute, but in this stage API Key and Secret still exposed!

    What's the alternate way to do like this but keep my secrecy matters invisible!

    below is my program.cs (perhaps I missed something in there)

    using Microsoft.AspNetCore.Authentication.Cookies;  
    using Microsoft.AspNetCore.DataProtection;  
    using Microsoft.AspNetCore.Mvc;  
    using Microsoft.AspNetCore.Server.Kestrel.Core;  
    using System.Configuration;  
    using Xtender;  
    using Xtender.Crontab;  
      
    var builder = WebApplication.CreateBuilder(args);  
      
    ...  
    ...  
    ...  
      
      
      
    string hosts = builder.Configuration.GetSection("CORS").Value;  
    Models.AppSettings.CORS.Hosts = hosts;  
      
    builder.Services.AddCors(options =>  
    {  
        options.AddPolicy(name: "_myAllowSpecificOrigins",  
                          builder =>  
                          {  
                              builder.WithOrigins(hosts);  
                          });  
    });  
      
    builder.Services.AddDataProtection()  
                    .SetApplicationName(Models.AppSettings.Application.Name)  
                    .PersistKeysToFileSystem(new DirectoryInfo(Models.AppSettings.Path.Key_Ring))  
                    .SetDefaultKeyLifetime(TimeSpan.FromDays(14));  
      
    builder.Services.AddDistributedMemoryCache();  
      
    // session matter, still in checking by the team  
    
    builder.Services.AddSession(so =>  
    {  
        so.Cookie.Name = "." + Models.AppSettings.Application.Cookie_Name;  
        so.Cookie.HttpOnly = true;  
        so.Cookie.IsEssential = true;  
        //so.IdleTimeout = TimeSpan.FromSeconds(20);// Security.Second_Idle_Timeout);  
    });  
      
    builder.Services.ConfigureApplicationCookie(options =>  
    {  
        // Cookie settings  
        //options.Cookie.HttpOnly = true;  
        //options.ExpireTimeSpan = TimeSpan.FromMinutes(5);  
      
        options.LoginPath = "/User/Login";  
        options.AccessDeniedPath = "/User/Login";  
        options.LogoutPath = "/User/Logout";  
        options.SlidingExpiration = true;  
    });  
      
    builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)  
    .AddCookie(options =>  
    {  
        options.LoginPath = "/User/Login";  
        options.AccessDeniedPath = "/User/Login";  
        options.LogoutPath = "/User/Logout";  
        options.SlidingExpiration = true;  
    });  
      
    builder.Services.AddHttpContextAccessor();  
    builder.Services.AddMemoryCache();  
      
    builder.Services.AddAntiforgery(opts => opts.Cookie.Name = "__RequestVerificationToken");  
    builder.Services.AddControllersWithViews()  
        .AddSessionStateTempDataProvider();  
      
      
    builder.Services.Configure<KestrelServerOptions>(options =>  
    {  
        options.AllowSynchronousIO = true;  
    });  
      
    builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();  
      
    builder.Services.Configure<CookiePolicyOptions>(options =>  
    {  
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.    
        options.CheckConsentNeeded = context => true;  
        options.MinimumSameSitePolicy = SameSiteMode.None;  
    });  
      
    builder.Services.AddMvc(option =>  
    {  
        option.EnableEndpointRouting = false;  
    }).AddNewtonsoftJson();  
      
    builder.Services.AddWebSocketManager();  
      
    // Add services to the container.  
    builder.Services.AddControllersWithViews();  
      
    if (!builder.Environment.IsDevelopment())  
    {  
        builder.WebHost.UseKestrel(serverOptions =>  
        {  
            serverOptions.ListenAnyIP(7073);  
        });  
    }  
      
    var app = builder.Build();  
      
    // Configure the HTTP request pipeline.  
    if (!app.Environment.IsDevelopment())  
    {  
        app.UseExceptionHandler("/Home/Error");  
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.  
        app.UseHsts();  
    }  
      
    app.UsePathBase(Xtender.Models.AppSettings.Path.Deployment);  
    app.UseCors(hosts);  
    app.UseCookiePolicy();  
    app.UseAuthentication();  
      
    #region Websocket  
      
    var serviceScopeFactory = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService<IServiceScopeFactory>();  
    var serviceProvider = serviceScopeFactory.CreateScope().ServiceProvider;  
    var webSocketOptions = new WebSocketOptions()  
    {  
        KeepAliveInterval = TimeSpan.FromSeconds(120)  
    };  
    webSocketOptions.AllowedOrigins.Add("*");  
    app.UseWebSockets(webSocketOptions);  
    app.MapWebSocketManager("/ws", serviceProvider.GetService<NotificationsMessageHandler>());  
      
    #endregion  
      
    app.UseHttpsRedirection();  
    app.UseStaticFiles();  
    app.UseRouting();  
    app.UseAuthorization();  
    app.UseSession();  
    app.MapControllerRoute(  
        name: "default",  
        pattern: "{controller=Home}/{action=Index}/{id?}");  
      
    app.Run();  
    
    
      
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.