You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Auth0实现仅订阅会员可见的测验应用授权?

Hey Terry, let's break this down step by step—this setup is totally doable once you map out the flow. I've built similar auth logic for subscription-only content before, so here's how I'd approach it:

1. Setting Up is_subscribed in app_metadata

First, you need a secure way to flag subscribed users in their auth profile. The app_metadata field is perfect for this because it’s meant for app-specific, non-user-editable data (unlike user_metadata, which users can modify themselves).

When a user completes their subscription (e.g., after paying via Stripe/PayPal), update their app_metadata from your backend never let the frontend handle this—it’s a critical security risk. Here’s a quick example using a common auth SDK (adapt this to your auth provider):

// Example: Update subscription status in app_metadata (Node.js)
const updateUserSubscription = async (userId) => {
  await authProvider.users.update({
    id: userId,
    app_metadata: {
      is_subscribed: true
      // Add extra fields like subscription_expiry if you need to track expiration
    }
  });
};

Don’t forget to handle cancellations too—set is_subscribed back to false when a user ends their plan.

2. Assigning Scopes for Subscription Access

Scopes add granular permission control, and pairing them with app_metadata creates a robust validation layer. Here’s how to tie them together:

Define a Subscription-Only Scope

First, create a scope like read:quiz-content that represents access to your quiz content. This makes it easy to check permissions later.

Auto-Assign the Scope to Subscribed Users

Use your auth provider’s "rules" or "hooks" feature to add this scope to the user’s access token only if their app_metadata.is_subscribed is true. For example (Auth0 rule, but most providers have similar functionality):

// Example: Auth Rule to add scope for subscribers
function (user, context, callback) {
  // Check if user has an active subscription
  if (user.app_metadata?.is_subscribed) {
    // Add the subscription-only scope to the access token
    if (!context.accessToken.scope) context.accessToken.scope = [];
    context.accessToken.scope.push('read:quiz-content');
  }
  callback(null, user, context);
}

This ensures only subscribed users get the scope needed to access quiz content.

3. Validating Access in Your Quiz App

You’ll need to check permissions in both frontend (for better UX) and backend (for security—never skip backend validation).

Frontend Check (For User Experience)

Before rendering quiz content, check if the user’s access token includes the read:quiz-content scope. This lets you show a subscription prompt immediately instead of waiting for a backend error:

// Example: Check scope in frontend (using jwt-decode)
import jwtDecode from 'jwt-decode';

const hasQuizAccess = () => {
  const accessToken = localStorage.getItem('access_token'); // Get your token from storage
  if (!accessToken) return false;
  
  const decodedToken = jwtDecode(accessToken);
  return decodedToken.scope?.includes('read:quiz-content');
};

// Use it in your UI
if (hasQuizAccess()) {
  renderQuizContent();
} else {
  renderSubscribeButton();
}

Backend Validation (For Security)

Every request for quiz content must go through a backend check to verify the user’s subscription status and scope. Here’s an Express.js middleware example:

// Example: Backend middleware to enforce subscription access
const jwt = require('jsonwebtoken');

const requireQuizAccess = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ message: 'Unauthorized' });
  }

  const token = authHeader.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    
    // Double validation: check both app_metadata and scope
    const hasValidSubscription = decoded.app_metadata?.is_subscribed || 
                                decoded.scope?.includes('read:quiz-content');
    
    if (!hasValidSubscription) {
      return res.status(403).json({ message: 'Subscription required to access this content' });
    }
    
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ message: 'Invalid token' });
  }
};

// Apply middleware to your quiz routes
app.get('/api/quiz/questions', requireQuizAccess, (req, res) => {
  res.json(quizQuestions); // Return your quiz content
});
4. Bonus Security Tips
  • Never rely solely on frontend checks: Users can manipulate frontend code to bypass restrictions—always validate every request on the backend.
  • Use short-lived access tokens: Pair them with refresh tokens to minimize the risk of token abuse.
  • Sync subscription status regularly: Set up a cron job or webhook to sync your auth provider’s app_metadata with your payment processor (e.g., Stripe webhook for subscription cancellations).

内容的提问来源于stack exchange,提问作者Terry Djony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:41:42