如何在Apostrophe CMS(含apostrophe-headless)实现前端专属用户登录?
Hey there! I’ve worked with Apostrophe’s headless setup and frontend user authentication before, so let me break down exactly how to fix your issue—stopping frontend users from accessing the admin UI while still letting them log into your frontend.
Step 1: Restrict Admin UI Access for Frontend Users
The core problem is that default apostrophe-user accounts might have implicit permissions to access the admin. We can override this by customizing the apostrophe-user module to block non-admin users from the backend.
Add this configuration to your app.js file:
modules: { 'apostrophe-user': { // Optional: Add a flag to mark frontend-only users addFields: [ { name: 'isFrontendOnly', label: 'Frontend-Only User', type: 'boolean', default: true, help: 'Check this to prevent the user from accessing the admin UI' } ], construct: function(self, options) { // Override the default admin access check const originalCanAdmin = self.canAdmin; self.canAdmin = function(req) { // Block any user marked as frontend-only if (req.user && req.user.isFrontendOnly) { return false; } // For other users, use the original admin permission logic return originalCanAdmin(req); }; } }, 'apostrophe-headless': { // Your existing headless config goes here // e.g., allowCors: true, etc. } }
Now when you create users, the isFrontendOnly flag will be checked—if it's true, they'll get a "permission denied" error if they try to access the admin login page (/login by default).
Step 2: Implement Frontend Login with apostrophe-headless
Apostrophe Headless provides a built-in API endpoint for authentication. Here's how to use it in your frontend:
Create a Login Form
Build a simple form with username/email and password fields. On submission, send aPOSTrequest to/api/v1/loginwith the credentials.Handle the Login Request
Example using JavaScript fetch:async function loginUser(username, password) { try { const response = await fetch('/api/v1/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); if (!response.ok) { throw new Error('Login failed'); } const data = await response.json(); // Save the JWT token to localStorage or cookies for future requests localStorage.setItem('apostrophe-token', data.token); // Redirect or update the UI to show logged-in state } catch (error) { // Handle login errors (invalid credentials, etc.) console.error(error); } }Authenticate Subsequent Requests
For any frontend requests that need user authentication (like fetching private content), include the token in theAuthorizationheader:async function getPrivateContent() { const token = localStorage.getItem('apostrophe-token'); const response = await fetch('/api/v1/my-private-content', { headers: { 'Authorization': `Bearer ${token}` } }); const content = await response.json(); // Use the content in your frontend }
Bonus: Customize Login Error Messages (Optional)
If you want to make it clearer why frontend users can't access the admin, you can override the login route's error handling in your custom apostrophe-user module, but the above setup is usually sufficient for most use cases.
That's it! With these changes, your frontend users will only be able to log into your frontend via the headless API, and they won't have any access to the Apostrophe admin UI.
内容的提问来源于stack exchange,提问作者Ben K.

