Dotkernel API authenticates with the OAuth2 password grant through mezzio/mezzio-authentication-oauth2.
Clients exchange credentials at POST /security/generate-token for an access token and a refresh token, then send the access token in the Authorization header; POST /security/refresh-token renews it.
Requests without an Authorization header get a default guest identity, which can reach only public endpoints.
Authentication is the process by which an identity is presented to the application. It ensures that the entity making the request has the proper credentials to access the API.
Dotkernel API identities are delivered to the application from the client through the Authorization request.
If it is present, the application tries to find and assign the identity to the application.
If it is not presented, Dotkernel API assigns a default guest identity, represented by an instance of the class Mezzio\Authentication\UserInterface.
Guests can access public endpoints but cannot access protected resources (those requiring user or admin roles).
Check out the Authorization page for more details on role-based access.
Dotkernel API uses the OAuth2 password grant flow for authentication. This allows users to exchange their credentials (username/password) for access tokens. These tokens are then used for later requests instead of repeatedly sending credentials.
Authentication in Dotkernel API is built around the mezzio/mezzio-authentication-oauth2 component and is already configured out of the box.
To customize authentication behavior (token lifetimes, algorithms, etc.), edit config/autoload/local.php under the authentication key.
See the Mezzio OAuth2 documentation for all available options.
You can check the mezzio/mezzio-authentication-oauth2 configuration part for more info.
Dotkernel API authentication system can be used for SPAs (single-page applications), mobile applications, and simple, token-based APIs. It allows each user of your application to generate API tokens for their accounts.
The authentication happens through the middleware in the Api\App\Middleware\AuthenticationMiddleware.
When you install Dotkernel API for the first time, you need to run the migrations and seeders (fixtures). All the tables required for authentication are automatically created and populated.
php ./vendor/bin/doctrine-migrations migrate
php ./bin/doctrine fixtures:execute
The commands above create OAuth tables (oauth_clients, oauth_scopes, oauth_*) and seed the initial credentials:
Check out the Installation Guide for more details.
In Dotkernel API, authenticated users come from either the admin or the user tables.
We chose to keep the admin and user tables separate to prevent users of the application from accessing sensitive data that only administrators should access.
Another table that is pre-populated is the oauth_scopes table, with the api scope.
Token generation in Dotkernel API is done using the password grant_type scenario, which in this case allows authentication to an API using the user's credentials (generally a username and password).
The POST /security/generate-token endpoint accepts OAuth2 credentials and returns both an access token (for making API calls) and a refresh token (for refreshing expired access tokens).
The client requires the following parameters:
| Field | Type | Purpose | Example |
|---|---|---|---|
grant_type |
string | OAuth2 flow type | "password" |
client_id |
string | OAuth client identifier from the oauth_clients table |
"frontend" |
client_secret |
string | OAuth client credential from the oauth_clients table |
"frontend" |
scope |
string | Permission scope from the oauth_scopes table |
"api" |
username |
string | User identity (email/username) from table admin/user |
"test@dotkernel.com" |
password |
string | User password | "dotkernel" |
This is what the call should look like:
POST /security/generate-token HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"grant_type": "password",
"client_id": "frontend",
"client_secret": "frontend",
"scope": "api",
"username": "test@dotkernel.com",
"password": "dotkernel"
}
The server responds with a JSON as follows:
{
"token_type": "Bearer",
"expires_in": 86400,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"refresh_token": "def5020087199939a49d0f2f818..."
}
| Field | Type | Lifetime | Purpose |
|---|---|---|---|
token_type |
string | N/A | Header value type |
expires_in |
integer | N/A | Seconds until access token expires |
access_token |
string | 86400 seconds = 1 day (configurable) | Used in Authorization header |
refresh_token |
string | 1 month (configurable) | Used to refresh expired access tokens |
On later requests to the server for an authenticated endpoint, the client should use the Authorization header request.
GET /users/1 HTTP/1.1
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
When an access token expires, use the refresh token (received during token generation) to obtain a new access token without re-entering credentials:
POST /security/refresh-token
Accept: application/json
Content-Type: application/json
{
"grant_type": "refresh_token",
"client_id": "frontend",
"client_secret": "frontend",
"scope": "api",
"refresh_token": "def5020087199939a49d0f2f818..."
}
The response contains a new access_token and refresh_token:
{
"token_type": "Bearer",
"expires_in": 86400,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"refresh_token": "def5020087199939a49d0f2f818..."
}
scope field is set to "api" (the only configured scope)User Credentials
↓
POST /security/generate-token
↓
Access Token + Refresh Token
↓
Store tokens securely ←─────────────────────────┐
↓ |
Include Access Token in Authorization header |
↓ |
Make API requests |
↓ |
Token expires? |
↓ (yes) |
POST /security/refresh-token with refresh_token |
↓ |
Get new Access Token ───────────────────────────┘
Q: What happens if a request sends no Authorization header?
A: The application assigns a default guest identity, an instance of Mezzio\Authentication\UserInterface.
Guests can reach public endpoints but not protected ones.
Q: Which OAuth2 grant does the API use?
A: The password grant: credentials are exchanged once for tokens, and subsequent requests carry the access token instead of the credentials.
Q: What must I run before authenticating for the first time?
A: The migrations and fixtures — php ./vendor/bin/doctrine-migrations migrate followed by php ./bin/doctrine fixtures:execute — which create the OAuth tables and seed the initial credentials.
See Doctrine ORM.
Q: What are the seeded credentials?
A: admin / dotadmin for the admin account and test@dotkernel.com / dotkernel for the user account.
Remove or change them before production.
See Basic security.
Q: Why are admins and users in separate tables?
A: To keep application users away from data that only administrators should reach.
Authenticated identities therefore come from either the admin or the user table.
Q: Which parameters does the token request need?
A: grant_type, client_id, client_secret, scope, username and password.
The client values come from oauth_clients and the scope from oauth_scopes.
Q: How long do the tokens last?
A: Access tokens expire after one day and refresh tokens after one month, both configurable under the authentication key in config/autoload/local.php.
Q: How do I renew an expired access token?
A: Post the refresh_token to /security/refresh-token with grant_type set to refresh_token.
If the refresh token has expired too, authenticate again with credentials.
Q: I get an "Invalid scope" error. What is wrong?
A: scope must be "api" — it is the only configured scope.
Q: I get "Invalid credentials" even though the password is right. What else could it be?
A: A mismatched client_id or client_secret against the oauth_clients table, or an account that does not exist or is inactive.
Q: Which middleware performs authentication?
A: Api\App\Middleware\AuthenticationMiddleware, which runs before authorization in the pipeline.
See Middleware flow.
Q: Is authenticating enough to access an endpoint?
A: No. Authentication establishes the identity; the role still needs permission for the route. See Authorization.