Skip to main content

Authentication Providers

SOLID supports multiple authentication methods through its provider system, offering flexibility in how users can sign up and log in to your application.

Supported Providers

Section Management

  • Traditional username/password
  • Password policies
  • Password reset flow
  • Account recovery

Section Management

  • Email-based OTP
  • SMS-based OTP
  • Time-based tokens
  • Recovery codes

Section Management

  1. Google
  2. Meta/Facebook
  3. LinkedIn
  4. Twitter/X
  5. Custom OAuth providers

Authentication Flow

Standard OAuth Flow

1. Frontend initiates auth:

// Redirect to OAuth provider
window.location.href = "https://solid.website.com/api/iam/[provider]/connect";

2. Backend handles callback:

https://solid.website.com/api/iam/[provider]/connect/callback

3. Provider redirects with code:

http://website.com/connect/[provider]/callback?accessCode=[code]

4. Frontend exchanges code:

GET https://solid.website.com/api/iam/[provider]/auth?accessCode=[code]

5. Backend returns JWT:

{
"token": "eyJhbGciOiJIUzI1...",
"user": {
"id": "123",
"email": "user@example.com",
"profile": {}
}
}

Provider Configuration

Standard OAuth Flow

{
"provider": "password",
"config": {
"minLength": 8,
"requireNumbers": true,
"requireSpecialChars": true,
"requireUppercase": true,
"passwordHistory": 5,
"maxAttempts": 5,
"lockoutDuration": 300
}
}

OTP Provider

{
"provider": "otp",
"config": {
"type": "email",
"codeLength": 6,
"expiry": 300,
"rateLimit": {
"window": 3600,
"max": 5
}
}
}

OAuth Provider (Google Example)

{
"provider": "google",
"config": {
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"redirectUri": "https://solid.website.com/api/iam/google/connect/callback",
"scopes": ["email", "profile"]
}
}

Features

Multi-factor Authentication (MFA)

  • Enable/disable per user
  • Multiple MFA methods
  • Backup codes
  • Remember device option

Session Management

  • JWT tokens
  • Refresh tokens
  • Token expiry
  • Session invalidation

Account Recovery

  • Email recovery
  • Security questions
  • Admin assistance
  • Recovery codes

Security Features

Password Security

  • Secure hashing (bcrypt)
  • Password policies
  • Brute force protection
  • Password history

OAuth Security

  • State parameter
  • PKCE support
  • Scope validation
  • Token validation

General Security

  • Rate limiting
  • IP blocking
  • Audit logging
  • Session monitoring

Implementation Examples

Adding Google Authentication

  1. Configure Provider:
{
"name": "google",
"enabled": true,
"config": {
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"redirectUri": "https://solid.website.com/api/iam/google/connect/callback",
"scopes": ["email", "profile"],
"mapping": {
"email": "email",
"name": "displayName",
"picture": "photoUrl"
}
}
}
  1. Frontend Integration:
function initiateGoogleAuth() {
window.location.href = "https://solid.website.com/api/iam/google/connect";
}

async function handleCallback(accessCode) {
const response = await fetch(
`https://solid.website.com/api/iam/google/auth?accessCode=${accessCode}`
);
const { token, user } = await response.json();
// Store token and handle user session
}

Implementing OTP Authentication

  1. Configure Provider:
{
"name": "email_otp",
"enabled": true,
"config": {
"type": "email",
"template": "auth_otp",
"codeLength": 6,
"expiry": 300,
"rateLimit": {
"window": 3600,
"max": 5
}
}
}
  1. Authentication Flow:
// Request OTP
async function requestOTP(email) {
await fetch("/api/iam/otp/request", {
method: "POST",
body: JSON.stringify({ email }),
});
}

// Verify OTP
async function verifyOTP(email, code) {
const response = await fetch("/api/iam/otp/verify", {
method: "POST",
body: JSON.stringify({ email, code }),
});
const { token, user } = await response.json();
// Handle successful authentication
}
@Auth(AuthType.None)
@Controller("iam/google")
@ApiTags("Iam")
export class GoogleAuthenticationController {
constructor(
@Inject(iamConfig.KEY)
private iamConfiguration: ConfigType<typeof iamConfig>,
private readonly userService: UserService,
private readonly authService: AuthenticationService
) {}

@Public()
@UseGuards(GoogleOauthGuard)
@Get("connect")
async connect() {
this.validateConfiguration();
}

private validateConfiguration() {
if (!isGoogleOAuthConfigured(this.iamConfiguration)) {
throw new InternalServerErrorException("Google OAuth is not configured");
}
}

@Public()
@Get("connect/callback")
@UseGuards(GoogleOauthGuard)
googleAuthCallback(@Req() req: Request, @Res() res: Response) {
this.validateConfiguration();
const user = req.user;

// console.log(`Found user: ${JSON.stringify(user)}`);
// const token = await this.authService.signIn(req.user);
// res.cookie('access_token', token, {
// maxAge: 2592000000,
// sameSite: true,
// secure: false,
// });
// return req.user;
// return res;

return res.redirect(
`${this.iamConfiguration.googleOauth.redirectURL}?accessCode=${user["accessCode"]}`
);
}

/**
* This is just a dummy endpoint where we are passing in the accessCode, this will be configured in the .env as an environment variable and
* will be passed the accessCode, using the accessCode the UI code on this page will mostly invoke the /iam/google/auth endpoint which will finally generate the JWT token.
*
* @param accessCode
* @returns
*/
@Public()
@Get("dummy-redirect")
async dummyGoogleAuthRedirect(@Query("accessCode") accessCode) {
this.validateConfiguration();
const user = await this.userService.findOneByAccessCode(accessCode);

delete user["password"];

return user;
}

/**
* Use this endpoint to authenticate using an accessCode with Google.
*
* @param accessCode
* @returns
*/
@Public()
@Get("authenticate")
@ApiQuery({ name: "accessCode", required: true, type: String })
async googleAuth(@Query("accessCode") accessCode) {
this.validateConfiguration();
return this.authService.signInUsingGoogle(accessCode);
}
}

Best Practices

Provider Selection

  • Consider user base
  • Evaluate security needs
  • Plan backup methods
  • Test all flows

Configuration

  • Secure credentials
  • Set proper timeouts
  • Configure rate limits
  • Enable logging

User Experience

  • Clear error messages
  • Simple recovery flows
  • Multiple auth options
  • Remember user preferences

Security

  • Regular audits
  • Monitor failed attempts
  • Review permissions
  • Update configurations