Skip to main content

Portal Authentication

End-user authentication allows you to secure your public feature portal by requiring users to authenticate before voting or suggesting features. This ensures that votes come from verified users in your system and prevents spam or manipulation.

How It Works

  1. You generate tokens server-side - When a user visits your feature portal, your backend generates a signed token containing their identity
  2. Pass the token to the portal - Include the token in the portal URL or embed code
  3. SeggWat validates the signature - SeggWat verifies the token hasn’t been tampered with
  4. User identity is confirmed - The user can vote/suggest with their verified identity

Setting Up Authentication

1. Enable Authentication in Project Settings

  1. Go to your project settings in the SeggWat dashboard
  2. Find the End-User Authentication section
  3. Select an authentication mode:
    • HMAC Signed - Simple signed tokens (recommended for most use cases)
    • JWT (HS256) - Standard JSON Web Tokens
  4. Configure which actions require authentication:
    • Voting on features
    • Suggesting new features
  5. Click Generate Secret to create your signing secret
Important: The signing secret is only shown once! Copy it immediately and store it securely in your backend environment variables.

2. Generate Tokens Server-Side

Generate tokens in your backend when users access the feature portal.

Token Payload

Both HMAC and JWT tokens use the same payload structure:
{
  "sub": "user-123",           // Required: User's unique ID in your system
  "email": "[email protected]", // Optional: User's email
  "name": "Jane Doe",          // Optional: User's display name
  "exp": 1706500000,           // Required: Expiration timestamp (Unix epoch)
  "iat": 1706496400,           // Required: Issued at timestamp (Unix epoch)
  "project_key": "abc123-..." // Required: Your SeggWat project key
}

HMAC Token Generation

const crypto = require('crypto');

function generateSeggwatToken(userId, userEmail, projectKey, signingSecret) {
  const payload = JSON.stringify({
    sub: userId,
    email: userEmail,
    exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour expiry
    iat: Math.floor(Date.now() / 1000),
    project_key: projectKey
  });

  // Create signature
  const signature = crypto
    .createHmac('sha256', signingSecret)
    .update(payload)
    .digest('base64url');

  // Token format: base64url(payload).base64url(signature)
  const encodedPayload = Buffer.from(payload).toString('base64url');
  return `${encodedPayload}.${signature}`;
}

// Usage
const token = generateSeggwatToken(
  user.id,
  user.email,
  process.env.SEGGWAT_PROJECT_KEY,
  process.env.SEGGWAT_SIGNING_SECRET
);

JWT Token Generation

If you prefer standard JWT tokens:
const jwt = require('jsonwebtoken');

function generateSeggwatJWT(userId, userEmail, projectKey, signingSecret) {
  return jwt.sign(
    {
      sub: userId,
      email: userEmail,
      project_key: projectKey
    },
    signingSecret,
    {
      algorithm: 'HS256',
      expiresIn: '1h'
    }
  );
}

3. Embed the Portal with Token

Pass the token to the feature portal via URL parameter:
<!-- Direct link -->
<a href="https://seggwat.com/p/YOUR_PROJECT_KEY?token=GENERATED_TOKEN">
  Feature Portal
</a>

<!-- Iframe embed -->
<iframe
  src="https://seggwat.com/p/YOUR_PROJECT_KEY?token=GENERATED_TOKEN&embed=true"
  width="100%"
  height="600"
  frameborder="0">
</iframe>

Dynamic Embedding Example

// Server-side: Generate token when rendering page
app.get('/features', (req, res) => {
  const token = generateSeggwatToken(
    req.user.id,
    req.user.email,
    process.env.SEGGWAT_PROJECT_KEY,
    process.env.SEGGWAT_SIGNING_SECRET
  );

  res.render('features', {
    portalUrl: `https://seggwat.com/p/${process.env.SEGGWAT_PROJECT_KEY}?token=${token}&embed=true`
  });
});

Security Considerations

Token Expiration

  • Recommended: 1-4 hours
  • Maximum allowed: 24 hours
  • Short-lived tokens reduce risk if compromised

Project Key Validation

Tokens include the project_key claim. SeggWat validates this matches the portal being accessed, preventing tokens from being reused across different projects.

Secret Storage

  • Store your signing secret in environment variables
  • Never expose it in client-side code
  • Rotate secrets periodically using the “Regenerate” button in settings

Troubleshooting

”Authentication required” Error

The portal requires a valid token but none was provided or it was invalid. Solutions:
  • Ensure you’re passing the token parameter in the URL
  • Verify the token hasn’t expired
  • Check that the project_key in the token matches the portal

”Invalid token” Error

The token signature verification failed. Solutions:
  • Verify you’re using the correct signing secret
  • Ensure the payload JSON is properly formatted
  • Check that base64url encoding is correct (no padding, - instead of +, _ instead of /)

“Token has expired” Error

The token’s exp claim is in the past. Solutions:
  • Generate fresh tokens for each page load
  • Increase token lifetime if needed (up to 24 hours)

Backward Compatibility

If authentication is disabled or not required for an action, the portal continues to work with enduser_id parameters for anonymous or client-identified users.