consolidate jwt settings and setup docker compose

This commit is contained in:
2025-07-21 16:41:06 -07:00
parent bd5a909bcd
commit dbc4d973f9
5 changed files with 60 additions and 30 deletions
+23 -4
View File
@@ -1,13 +1,32 @@
Payment_Service=StripeIntent # Options are [ StripeIntent ] #############
## Payment ##
#############
# Options are [ StripeIntent ]
Payment_Service=StripeIntent
# StripeIntent Options
Stripe_PublicKey= Stripe_PublicKey=
Stripe_PublicKey= Stripe_PublicKey=
Stripe_Endpoint_Secret= Stripe_Endpoint_Secret=
MySQL_Server=mistox-database ####################
## Authentication ##
####################
# Random secret token for encrypting JWT contents
JWT_Secret=
##############
## Database ##
##############
MySQL_User=root MySQL_User=root
MySQL_Database=mistox MySQL_Pass=oasv34$8gpv023dd
MySQL_Pass=oasv34$8gpv023dd # Random value for the server and MySQL to communicate with
##############
## Email ##
##############
Email_Server= # Hostname of email server Email_Server= # Hostname of email server
Email_Port= # SMTP port used Email_Port= # SMTP port used
+3 -2
View File
@@ -5,18 +5,19 @@ services:
image: docker.mistox.net/boredcareers-website:latest image: docker.mistox.net/boredcareers-website:latest
restart: always restart: always
environment: environment:
- MySQLServer=boredcareers-database
- MySQLDatabase=boredcareers
- PaymentService=${Payment_Service} - PaymentService=${Payment_Service}
- StripePublicKey=${Stripe_PublicKey} - StripePublicKey=${Stripe_PublicKey}
- StripeApiKey=${Stripe_ApiKey} - StripeApiKey=${Stripe_ApiKey}
- StripeEndpointSecret=&{Stripe_Endpoint_Secret} - StripeEndpointSecret=&{Stripe_Endpoint_Secret}
- MySQLServer=${MySQL_Server}
- MySQLUser=${MySQL_User} - MySQLUser=${MySQL_User}
- MySQLPass=${MySQL_Pass} - MySQLPass=${MySQL_Pass}
- MySQLDatabase=${MySQL_Database}
- EmailServer=${Email_Server} - EmailServer=${Email_Server}
- EmailPort=${Email_Port} - EmailPort=${Email_Port}
- EmailAddress=${Email_Address} - EmailAddress=${Email_Address}
- EmailPassword=${Email_Password} - EmailPassword=${Email_Password}
- JWTsecret=${JWT_Secret}
ports: ports:
- 5000:5000 - 5000:5000
depends_on: depends_on:
@@ -1,7 +1,4 @@
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using BoredCareers.Services; using BoredCareers.Services;
using BoredCareers.Services.DatabaseService; using BoredCareers.Services.DatabaseService;
using BoredCareers.Entities; using BoredCareers.Entities;
+14 -7
View File
@@ -1,4 +1,3 @@
using Microsoft.AspNetCore.Authentication.Cookies;
using BoredCareers.Controllers.Payment; using BoredCareers.Controllers.Payment;
using BoredCareers.Services; using BoredCareers.Services;
using BoredCareers.Services.DatabaseService; using BoredCareers.Services.DatabaseService;
@@ -7,7 +6,6 @@ using Stripe;
using System.Security.Claims; using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Org.BouncyCastle.Bcpg.Sig;
using System.Text; using System.Text;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
@@ -41,6 +39,15 @@ string dbPass = !string.IsNullOrEmpty(_dbpass) ? _dbpass : "oasv34$8gpv023dd";
DatabaseService databaseService = new DatabaseService(connectionString: "server=" + dbserver + ";user=" + dbUser + ";database=" + dbdatabase + ";password=" + dbPass + ";port=3306;"); DatabaseService databaseService = new DatabaseService(connectionString: "server=" + dbserver + ";user=" + dbUser + ";database=" + dbdatabase + ";password=" + dbPass + ";port=3306;");
builder.Services.Add( new ServiceDescriptor( typeof( DatabaseService ), databaseService ) ); builder.Services.Add( new ServiceDescriptor( typeof( DatabaseService ), databaseService ) );
////////////////////////////////
////////// Auth Service ////////
////////////////////////////////
// Address
string? _jwtSecret = Environment.GetEnvironmentVariable("JWTsecret");
string JWTsecret = !string.IsNullOrEmpty(_jwtSecret) ? _jwtSecret : "v0Ftluhdh7Nht8^2b5eaiC^IS^VS1ku0VBs3j*B2";
BoredCareersJWT.TokenSecretKey = JWTsecret;
//////////////////////////////// ////////////////////////////////
///////// Email Service //////// ///////// Email Service ////////
//////////////////////////////// ////////////////////////////////
@@ -95,14 +102,14 @@ builder.Services.AddAuthentication(options => {
ValidateAudience = true, ValidateAudience = true,
ValidateLifetime = true, ValidateLifetime = true,
ValidateIssuerSigningKey = true, ValidateIssuerSigningKey = true,
ValidIssuer = "your-app", ValidIssuer = BoredCareersJWT.TokenIssuer,
ValidAudience = "your-app", ValidAudience = BoredCareersJWT.TokenAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("secret-key")), IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(BoredCareersJWT.TokenSecretKey)),
ClockSkew = TimeSpan.FromMinutes(1) ClockSkew = TimeSpan.FromMinutes(1)
}; };
options.Events = new JwtBearerEvents { options.Events = new JwtBearerEvents {
OnMessageReceived = context => { OnMessageReceived = context => {
context.Token = context.Request.Cookies["access_token"]; context.Token = context.Request.Cookies[BoredCareersJWT.TokenName];
return Task.CompletedTask; return Task.CompletedTask;
}, },
OnTokenValidated = context => { OnTokenValidated = context => {
@@ -110,7 +117,7 @@ builder.Services.AddAuthentication(options => {
if (jwtToken != null) { if (jwtToken != null) {
var exp = jwtToken.ValidTo; var exp = jwtToken.ValidTo;
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
if ((exp - now) < TimeSpan.FromMinutes(5)) { if ((exp - now) < TimeSpan.FromDays(3)) {
int accountID = Convert.ToInt32(context.Principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value); int accountID = Convert.ToInt32(context.Principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value);
bool isPersistent = bool.Parse(context.Principal?.FindFirst(ClaimTypes.IsPersistent)?.Value); bool isPersistent = bool.Parse(context.Principal?.FindFirst(ClaimTypes.IsPersistent)?.Value);
var newJWT = BoredCareersJWT.GenereateJWTToken(accountID, isPersistent); var newJWT = BoredCareersJWT.GenereateJWTToken(accountID, isPersistent);
+19 -13
View File
@@ -1,26 +1,33 @@
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Runtime.CompilerServices;
using System.Security.Claims; using System.Security.Claims;
using System.Text; using System.Text;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
namespace BoredCareers.Services { namespace BoredCareers.Services {
public class BoredCareersJWT { public class BoredCareersJWT {
public static string TokenAudience = "https://boredcareers.com/api";
public static string TokenIssuer = "https://boredcareers.com";
public static string TokenSecretKey = "";
public static string TokenName = "mistox_session";
public static string GenereateJWTToken(int accountID, bool StayLoggedIn) { public static string GenereateJWTToken(int accountID, bool StayLoggedIn) {
var tokenHandler = new JwtSecurityTokenHandler(); var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes("your-super-secret-key"); var key = Encoding.UTF8.GetBytes(TokenSecretKey);
var tokenDiscriptor = new SecurityTokenDescriptor { var tokenDiscriptor = new SecurityTokenDescriptor {
Subject = new ClaimsIdentity(new[] { Subject = new ClaimsIdentity([
new Claim(ClaimTypes.NameIdentifier, accountID.ToString()), new Claim(ClaimTypes.NameIdentifier, accountID.ToString()),
new Claim(ClaimTypes.IsPersistent, StayLoggedIn.ToString()) new Claim(ClaimTypes.IsPersistent, StayLoggedIn.ToString())
}), ]),
Expires = DateTime.UtcNow.AddMinutes(15), Expires = DateTime.UtcNow.AddDays(7),
IssuedAt = DateTime.UtcNow, IssuedAt = DateTime.UtcNow,
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.RsaSha512), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256),
Audience = "your-app", Audience = TokenAudience,
Issuer = "your-app" Issuer = TokenIssuer
}; };
var token = tokenHandler.CreateToken(tokenDiscriptor); var token = tokenHandler.CreateToken(tokenDiscriptor);
@@ -30,16 +37,15 @@ namespace BoredCareers.Services {
public static void SignIn(HttpResponse Response, bool StayLoggedIn, string jwt) { public static void SignIn(HttpResponse Response, bool StayLoggedIn, string jwt) {
if (StayLoggedIn) { if (StayLoggedIn) {
// Stay logged in cookie // Stay logged in cookie
Response.Cookies.Append("access_token", jwt, new CookieOptions { Response.Cookies.Append(TokenName, jwt, new CookieOptions {
Secure = true, Secure = true,
HttpOnly = true, HttpOnly = true,
SameSite = SameSiteMode.Strict, SameSite = SameSiteMode.Strict,
Expires = DateTime.UtcNow.AddMinutes(15) Expires = DateTime.UtcNow.AddDays(7)
}); });
} } else {
else {
// Session cookie // Session cookie
Response.Cookies.Append("access_token", jwt, new CookieOptions { Response.Cookies.Append(TokenName, jwt, new CookieOptions {
Secure = true, Secure = true,
HttpOnly = true, HttpOnly = true,
SameSite = SameSiteMode.Strict, SameSite = SameSiteMode.Strict,
@@ -48,7 +54,7 @@ namespace BoredCareers.Services {
} }
public static void SignOut(HttpResponse Response) { public static void SignOut(HttpResponse Response) {
Response.Cookies.Delete("access_token"); Response.Cookies.Delete(TokenName);
} }
} }
} }