Three login methods: password, magic link (passwordless) and OAuth (60+ providers via KnpUOAuth2ClientBundle).
The response is identical for unknown addresses, so the form does not reveal which accounts exist. If OAuth is configured, provider buttons also appear on the login page.
Users can be defined in config/users.yaml and synced to the database by the flat extension, to version-control who has access.
users:
- email: admin@example.com
roles: [ROLE_SUPER_ADMIN]
locale: en
username: Admin
- email: editor@example.com
roles: [ROLE_EDITOR]
locale: fr
username: Editor
php bin/console pw:flat:user-sync # users only
php bin/console pw:flat:sync # pages, media and users
config/users.yaml, user sync is skipped and no user is touched.Step 1 of the login form emails every existing account two links:
Their tokens are:
composer require knpuniversity/oauth2-client-bundle
composer require league/oauth2-google # Google
composer require thenetworg/oauth2-azure # Microsoft/Azure
composer require league/oauth2-github # GitHub
composer require league/oauth2-facebook # Facebook
# Full list: https://github.com/thephpleague/oauth2-client/blob/master/docs/providers/thirdparty.md
config/packages/knpu_oauth2_client.yaml with redirect_route: pushword_oauth_check and redirect_params: { provider: <name> } — see the provider examples below. A login button appears for each configured provider.OAuth never creates users: only accounts that already exist (from users.yaml or the admin) can log in, and an unknown email is refused.
https://your-domain.com/login/oauth/google/checkConfiguration:
# config/packages/knpu_oauth2_client.yaml
knpu_oauth2_client:
clients:
google:
type: google
client_id: '%env(OAUTH_GOOGLE_CLIENT_ID)%'
client_secret: '%env(OAUTH_GOOGLE_CLIENT_SECRET)%'
redirect_route: pushword_oauth_check
redirect_params: { provider: google }
access_type: online
# Optional: restrict to Google Workspace domain
hosted_domain: '%env(default::OAUTH_GOOGLE_HOSTED_DOMAIN)%'
https://your-domain.com/login/oauth/microsoft/checkConfiguration:
# config/packages/knpu_oauth2_client.yaml
knpu_oauth2_client:
clients:
microsoft:
type: azure
client_id: '%env(OAUTH_MICROSOFT_CLIENT_ID)%'
client_secret: '%env(OAUTH_MICROSOFT_CLIENT_SECRET)%'
redirect_route: pushword_oauth_check
redirect_params: { provider: microsoft }
# Optional: restrict to specific tenant (default: "common" for any account)
tenant: '%env(default:oauth_microsoft_tenant_default:OAUTH_MICROSOFT_TENANT)%'
parameters:
oauth_microsoft_tenant_default: common
https://your-domain.com/login/oauth/github/checkConfiguration:
# config/packages/knpu_oauth2_client.yaml
knpu_oauth2_client:
clients:
github:
type: github
client_id: '%env(OAUTH_GITHUB_CLIENT_ID)%'
client_secret: '%env(OAUTH_GITHUB_CLIENT_SECRET)%'
redirect_route: pushword_oauth_check
redirect_params: { provider: github }
Add your OAuth credentials to .env.local:
# Google
OAUTH_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
OAUTH_GOOGLE_CLIENT_SECRET=your-client-secret
# Microsoft
OAUTH_MICROSOFT_CLIENT_ID=your-azure-client-id
OAUTH_MICROSOFT_CLIENT_SECRET=your-azure-client-secret
# GitHub
OAUTH_GITHUB_CLIENT_ID=your-github-client-id
OAUTH_GITHUB_CLIENT_SECRET=your-github-client-secret
For local development, use https://localhost or https://127.0.0.1 as your redirect URI in the OAuth provider console. You may need to run your Symfony server with HTTPS:
symfony server:ca:install
symfony server:start
A super administrator can browse the admin as any account that reaches ROLE_EDITOR, from Log in as in the row menu of the user list. An amber banner then stays at the top of every admin page until its Back to my account button returns you to the user list under your own session.
Every change made meanwhile is saved under the borrowed account: a page’s editedBy names that editor, not you.
This is Symfony’s switch_user: ?_switch_user=<email> starts it and ?_switch_user=_exit ends it, on any URL. Only ROLE_ALLOWED_TO_SWITCH may switch, and ROLE_SUPER_ADMIN is the only role that inherits it.
.env.local or environment variables.OAUTH_GOOGLE_HOSTED_DOMAIN to limit to your organizationOAUTH_MICROSOFT_TENANT instead of “common”The OAuth email doesn’t match any user in the database. Add the user to config/users.yaml and run:
php bin/console pw:flat:user-sync
The OAuth provider didn’t return an email. Ensure your OAuth app has the email scope permission configured in the provider’s console.
knpuniversity/oauth2-client-bundle is installedconfig/packages/knpu_oauth2_client.yaml configuration exists and is validphp bin/console cache:clear.env: MAILER_DSN=smtp://user:pass@smtp.example.com:587